@spfn/cms 0.1.0-alpha.6 → 0.1.0-alpha.60
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/dist/actions.d.ts +140 -6
- package/dist/actions.js +97 -10
- package/dist/actions.js.map +1 -1
- package/dist/client.d.ts +43 -9
- package/dist/client.js +406 -56
- package/dist/client.js.map +1 -1
- package/dist/contracts/labels.d.ts +149 -0
- package/dist/contracts/labels.js +166 -0
- package/dist/contracts/labels.js.map +1 -0
- package/dist/contracts/published-cache.d.ts +25 -0
- package/dist/contracts/published-cache.js +32 -0
- package/dist/contracts/published-cache.js.map +1 -0
- package/dist/contracts/values.d.ts +69 -0
- package/dist/contracts/values.js +100 -0
- package/dist/contracts/values.js.map +1 -0
- package/dist/entities/cms-audit-logs.d.ts +15 -70
- package/dist/entities/cms-audit-logs.js +75 -100
- package/dist/entities/cms-audit-logs.js.map +1 -1
- package/dist/entities/cms-draft-cache.d.ts +13 -73
- package/dist/entities/cms-draft-cache.js +35 -109
- package/dist/entities/cms-draft-cache.js.map +1 -1
- package/dist/entities/cms-label-values.d.ts +14 -65
- package/dist/entities/cms-label-values.js +78 -102
- package/dist/entities/cms-label-values.js.map +1 -1
- package/dist/entities/cms-label-versions.d.ts +16 -49
- package/dist/entities/cms-label-versions.js +73 -77
- package/dist/entities/cms-label-versions.js.map +1 -1
- package/dist/entities/cms-labels.d.ts +17 -14
- package/dist/entities/cms-labels.js +39 -45
- package/dist/entities/cms-labels.js.map +1 -1
- package/dist/entities/cms-published-cache.d.ts +14 -69
- package/dist/entities/cms-published-cache.js +33 -100
- package/dist/entities/cms-published-cache.js.map +1 -1
- package/dist/entities/index.d.ts +7 -10
- package/dist/entities/index.js +217 -9
- package/dist/entities/index.js.map +1 -1
- package/dist/generators/index.d.ts +8 -7
- package/dist/generators/index.js +657 -17
- package/dist/generators/index.js.map +1 -1
- package/dist/index.d.ts +134 -20
- package/dist/index.js +1115 -23
- package/dist/index.js.map +1 -1
- package/dist/{generators/label-sync-generator.d.ts → label-sync-generator-lQrcVfja.d.ts} +9 -6
- package/dist/labels/index.d.ts +31 -4
- package/dist/labels/index.js +31 -6
- package/dist/labels/index.js.map +1 -1
- package/dist/repositories/index.d.ts +205 -6
- package/dist/repositories/index.js +435 -8
- package/dist/repositories/index.js.map +1 -1
- package/dist/routes/labels/[id]/index.js +499 -89
- package/dist/routes/labels/[id]/index.js.map +1 -1
- package/dist/routes/labels/{[id] → _id_}/index.d.ts +5 -3
- package/dist/routes/labels/by-key/[key]/index.js +453 -29
- package/dist/routes/labels/by-key/[key]/index.js.map +1 -1
- package/dist/routes/labels/by-key/_key_/index.d.ts +10 -0
- package/dist/routes/labels/index.d.ts +5 -3
- package/dist/routes/labels/index.js +488 -68
- package/dist/routes/labels/index.js.map +1 -1
- package/dist/routes/published-cache/index.d.ts +5 -3
- package/dist/routes/published-cache/index.js +325 -30
- package/dist/routes/published-cache/index.js.map +1 -1
- package/dist/routes/values/[labelId]/[version]/index.js +467 -41
- package/dist/routes/values/[labelId]/[version]/index.js.map +1 -1
- package/dist/routes/values/[labelId]/index.js +463 -39
- package/dist/routes/values/[labelId]/index.js.map +1 -1
- package/dist/routes/values/_labelId_/_version_/index.d.ts +10 -0
- package/dist/routes/values/_labelId_/index.d.ts +10 -0
- package/dist/server.d.ts +17 -7
- package/dist/server.js +263 -252
- package/dist/server.js.map +1 -1
- package/dist/store.d.ts +8 -14
- package/dist/store.js +396 -198
- package/dist/store.js.map +1 -1
- package/dist/types.d.ts +14 -7
- package/dist/types.js +0 -6
- package/dist/types.js.map +1 -1
- package/migrations/0000_condemned_centennial.sql +89 -0
- package/migrations/meta/0000_snapshot.json +687 -0
- package/migrations/meta/_journal.json +13 -0
- package/package.json +33 -16
- 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-draft-cache.d.ts.map +0 -1
- package/dist/entities/cms-label-values.d.ts.map +0 -1
- package/dist/entities/cms-label-versions.d.ts.map +0 -1
- package/dist/entities/cms-labels.d.ts.map +0 -1
- package/dist/entities/cms-published-cache.d.ts.map +0 -1
- package/dist/entities/index.d.ts.map +0 -1
- package/dist/generators/index.d.ts.map +0 -1
- 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 +0 -132
- 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.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.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/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/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.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.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]/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/server.d.ts.map +0 -1
- package/dist/store.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
// src/contracts/labels.ts
|
|
2
|
+
import { Type } from "@sinclair/typebox";
|
|
3
|
+
var getLabelsContract = {
|
|
4
|
+
method: "GET",
|
|
5
|
+
path: "/cms/labels",
|
|
6
|
+
query: Type.Object({
|
|
7
|
+
section: Type.Optional(Type.String({ description: "\uC139\uC158\uC73C\uB85C \uD544\uD130\uB9C1 (\uC608: home, why-futureplay)" })),
|
|
8
|
+
limit: Type.Optional(Type.Number({ minimum: 1, maximum: 100, default: 20, description: "\uD398\uC774\uC9C0\uB2F9 \uD56D\uBAA9 \uC218" })),
|
|
9
|
+
offset: Type.Optional(Type.Number({ minimum: 0, default: 0, description: "\uC2DC\uC791 \uC624\uD504\uC14B" }))
|
|
10
|
+
}),
|
|
11
|
+
response: Type.Object({
|
|
12
|
+
labels: Type.Array(Type.Object({
|
|
13
|
+
id: Type.Number(),
|
|
14
|
+
key: Type.String(),
|
|
15
|
+
section: Type.String(),
|
|
16
|
+
type: Type.String(),
|
|
17
|
+
publishedVersion: Type.Union([Type.Number(), Type.Null()]),
|
|
18
|
+
createdBy: Type.Union([Type.String(), Type.Null()]),
|
|
19
|
+
createdAt: Type.String(),
|
|
20
|
+
updatedAt: Type.String()
|
|
21
|
+
})),
|
|
22
|
+
total: Type.Number(),
|
|
23
|
+
limit: Type.Number(),
|
|
24
|
+
offset: Type.Number()
|
|
25
|
+
})
|
|
26
|
+
};
|
|
27
|
+
var createLabelContract = {
|
|
28
|
+
method: "POST",
|
|
29
|
+
path: "/cms/labels",
|
|
30
|
+
body: Type.Object({
|
|
31
|
+
key: Type.String({
|
|
32
|
+
description: "\uACE0\uC720 \uD0A4 (\uC608: home.hero.title)",
|
|
33
|
+
pattern: "^[a-z0-9-]+\\.[a-z0-9-]+\\.[a-z0-9-]+$"
|
|
34
|
+
}),
|
|
35
|
+
section: Type.String({
|
|
36
|
+
description: "\uC139\uC158 \uC774\uB984 (\uC608: home, why-futureplay)",
|
|
37
|
+
pattern: "^[a-z0-9-]+$"
|
|
38
|
+
}),
|
|
39
|
+
type: Type.Union([
|
|
40
|
+
Type.Literal("text"),
|
|
41
|
+
Type.Literal("image"),
|
|
42
|
+
Type.Literal("video"),
|
|
43
|
+
Type.Literal("file"),
|
|
44
|
+
Type.Literal("object")
|
|
45
|
+
], { description: "\uAC12 \uD0C0\uC785" }),
|
|
46
|
+
createdBy: Type.Optional(Type.String({ description: "\uC0DD\uC131\uC790 ID" }))
|
|
47
|
+
}),
|
|
48
|
+
response: Type.Union([
|
|
49
|
+
Type.Object({
|
|
50
|
+
id: Type.Number(),
|
|
51
|
+
key: Type.String(),
|
|
52
|
+
section: Type.String(),
|
|
53
|
+
type: Type.String(),
|
|
54
|
+
publishedVersion: Type.Union([Type.Number(), Type.Null()]),
|
|
55
|
+
createdBy: Type.Union([Type.String(), Type.Null()]),
|
|
56
|
+
createdAt: Type.String(),
|
|
57
|
+
updatedAt: Type.String()
|
|
58
|
+
}),
|
|
59
|
+
Type.Object({
|
|
60
|
+
error: Type.String(),
|
|
61
|
+
key: Type.Optional(Type.String())
|
|
62
|
+
})
|
|
63
|
+
])
|
|
64
|
+
};
|
|
65
|
+
var getLabelContract = {
|
|
66
|
+
method: "GET",
|
|
67
|
+
path: "/cms/labels/:id",
|
|
68
|
+
params: Type.Object({
|
|
69
|
+
id: Type.String({ description: "\uB77C\uBCA8 ID" })
|
|
70
|
+
}),
|
|
71
|
+
response: Type.Union([
|
|
72
|
+
Type.Object({
|
|
73
|
+
id: Type.Number(),
|
|
74
|
+
key: Type.String(),
|
|
75
|
+
section: Type.String(),
|
|
76
|
+
type: Type.String(),
|
|
77
|
+
publishedVersion: Type.Union([Type.Number(), Type.Null()]),
|
|
78
|
+
createdBy: Type.Union([Type.String(), Type.Null()]),
|
|
79
|
+
createdAt: Type.String(),
|
|
80
|
+
updatedAt: Type.String()
|
|
81
|
+
}),
|
|
82
|
+
Type.Object({
|
|
83
|
+
error: Type.String()
|
|
84
|
+
})
|
|
85
|
+
])
|
|
86
|
+
};
|
|
87
|
+
var updateLabelContract = {
|
|
88
|
+
method: "PATCH",
|
|
89
|
+
path: "/cms/labels/:id",
|
|
90
|
+
params: Type.Object({
|
|
91
|
+
id: Type.String({ description: "\uB77C\uBCA8 ID" })
|
|
92
|
+
}),
|
|
93
|
+
body: Type.Object({
|
|
94
|
+
section: Type.Optional(Type.String({ description: "\uC139\uC158 \uBCC0\uACBD" })),
|
|
95
|
+
type: Type.Optional(Type.Union([
|
|
96
|
+
Type.Literal("text"),
|
|
97
|
+
Type.Literal("image"),
|
|
98
|
+
Type.Literal("video"),
|
|
99
|
+
Type.Literal("file"),
|
|
100
|
+
Type.Literal("object")
|
|
101
|
+
]))
|
|
102
|
+
}),
|
|
103
|
+
response: Type.Union([
|
|
104
|
+
Type.Object({
|
|
105
|
+
id: Type.Number(),
|
|
106
|
+
key: Type.String(),
|
|
107
|
+
section: Type.String(),
|
|
108
|
+
type: Type.String(),
|
|
109
|
+
publishedVersion: Type.Union([Type.Number(), Type.Null()]),
|
|
110
|
+
createdBy: Type.Union([Type.String(), Type.Null()]),
|
|
111
|
+
createdAt: Type.String(),
|
|
112
|
+
updatedAt: Type.String()
|
|
113
|
+
}),
|
|
114
|
+
Type.Object({
|
|
115
|
+
error: Type.String()
|
|
116
|
+
})
|
|
117
|
+
])
|
|
118
|
+
};
|
|
119
|
+
var deleteLabelContract = {
|
|
120
|
+
method: "DELETE",
|
|
121
|
+
path: "/cms/labels/:id",
|
|
122
|
+
params: Type.Object({
|
|
123
|
+
id: Type.String({ description: "\uB77C\uBCA8 ID" })
|
|
124
|
+
}),
|
|
125
|
+
response: Type.Union([
|
|
126
|
+
Type.Object({
|
|
127
|
+
success: Type.Boolean(),
|
|
128
|
+
id: Type.Number()
|
|
129
|
+
}),
|
|
130
|
+
Type.Object({
|
|
131
|
+
error: Type.String()
|
|
132
|
+
})
|
|
133
|
+
])
|
|
134
|
+
};
|
|
135
|
+
var getLabelByKeyContract = {
|
|
136
|
+
method: "GET",
|
|
137
|
+
path: "/cms/labels/by-key/:key",
|
|
138
|
+
params: Type.Object({
|
|
139
|
+
key: Type.String({ description: "\uB77C\uBCA8 Key (\uC608: home.hero.title)" })
|
|
140
|
+
}),
|
|
141
|
+
response: Type.Union([
|
|
142
|
+
Type.Object({
|
|
143
|
+
id: Type.Number(),
|
|
144
|
+
key: Type.String(),
|
|
145
|
+
section: Type.String(),
|
|
146
|
+
type: Type.String(),
|
|
147
|
+
publishedVersion: Type.Union([Type.Number(), Type.Null()]),
|
|
148
|
+
createdBy: Type.Union([Type.String(), Type.Null()]),
|
|
149
|
+
createdAt: Type.String(),
|
|
150
|
+
updatedAt: Type.String()
|
|
151
|
+
}),
|
|
152
|
+
Type.Object({
|
|
153
|
+
error: Type.String(),
|
|
154
|
+
key: Type.Optional(Type.String())
|
|
155
|
+
})
|
|
156
|
+
])
|
|
157
|
+
};
|
|
158
|
+
export {
|
|
159
|
+
createLabelContract,
|
|
160
|
+
deleteLabelContract,
|
|
161
|
+
getLabelByKeyContract,
|
|
162
|
+
getLabelContract,
|
|
163
|
+
getLabelsContract,
|
|
164
|
+
updateLabelContract
|
|
165
|
+
};
|
|
166
|
+
//# sourceMappingURL=labels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/contracts/labels.ts"],"sourcesContent":["import { Type } from '@sinclair/typebox';\nimport type { RouteContract } from '@spfn/core/route';\n\n/**\n * CMS Labels Contracts\n *\n * 라벨 메타데이터 관리 API\n */\n\n/**\n * GET /cms/labels - 라벨 목록 조회\n */\nexport const getLabelsContract = {\n method: 'GET' as const,\n path: '/cms/labels',\n query: Type.Object({\n section: Type.Optional(Type.String({ description: '섹션으로 필터링 (예: home, why-futureplay)' })),\n limit: Type.Optional(Type.Number({ minimum: 1, maximum: 100, default: 20, description: '페이지당 항목 수' })),\n offset: Type.Optional(Type.Number({ minimum: 0, default: 0, description: '시작 오프셋' }))\n }),\n response: Type.Object({\n labels: Type.Array(Type.Object({\n id: Type.Number(),\n key: Type.String(),\n section: Type.String(),\n type: Type.String(),\n publishedVersion: Type.Union([Type.Number(), Type.Null()]),\n createdBy: Type.Union([Type.String(), Type.Null()]),\n createdAt: Type.String(),\n updatedAt: Type.String()\n })),\n total: Type.Number(),\n limit: Type.Number(),\n offset: Type.Number()\n })\n} as const satisfies RouteContract;\n\n/**\n * POST /cms/labels - 새 라벨 생성\n */\nexport const createLabelContract = {\n method: 'POST' as const,\n path: '/cms/labels',\n body: Type.Object({\n key: Type.String({\n description: '고유 키 (예: home.hero.title)',\n pattern: '^[a-z0-9-]+\\\\.[a-z0-9-]+\\\\.[a-z0-9-]+$'\n }),\n section: Type.String({\n description: '섹션 이름 (예: home, why-futureplay)',\n pattern: '^[a-z0-9-]+$'\n }),\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 ], { description: '값 타입' }),\n createdBy: Type.Optional(Type.String({ description: '생성자 ID' }))\n }),\n response: Type.Union([\n Type.Object({\n id: Type.Number(),\n key: Type.String(),\n section: Type.String(),\n type: Type.String(),\n publishedVersion: Type.Union([Type.Number(), Type.Null()]),\n createdBy: Type.Union([Type.String(), Type.Null()]),\n createdAt: Type.String(),\n updatedAt: Type.String()\n }),\n Type.Object({\n error: Type.String(),\n key: Type.Optional(Type.String())\n })\n ])\n} as const satisfies RouteContract;\n\n/**\n * GET /cms/labels/:id - 라벨 단건 조회\n */\nexport const getLabelContract = {\n method: 'GET' as const,\n path: '/cms/labels/:id',\n params: Type.Object({\n id: Type.String({ description: '라벨 ID' })\n }),\n response: Type.Union([\n Type.Object({\n id: Type.Number(),\n key: Type.String(),\n section: Type.String(),\n type: Type.String(),\n publishedVersion: Type.Union([Type.Number(), Type.Null()]),\n createdBy: Type.Union([Type.String(), Type.Null()]),\n createdAt: Type.String(),\n updatedAt: Type.String()\n }),\n Type.Object({\n error: Type.String()\n })\n ])\n} as const satisfies RouteContract;\n\n/**\n * PATCH /cms/labels/:id - 라벨 메타데이터 수정\n */\nexport const updateLabelContract = {\n method: 'PATCH' as const,\n path: '/cms/labels/:id',\n params: Type.Object({\n id: Type.String({ description: '라벨 ID' })\n }),\n body: Type.Object({\n section: Type.Optional(Type.String({ description: '섹션 변경' })),\n type: Type.Optional(Type.Union([\n Type.Literal('text'),\n Type.Literal('image'),\n Type.Literal('video'),\n Type.Literal('file'),\n Type.Literal('object')\n ]))\n }),\n response: Type.Union([\n Type.Object({\n id: Type.Number(),\n key: Type.String(),\n section: Type.String(),\n type: Type.String(),\n publishedVersion: Type.Union([Type.Number(), Type.Null()]),\n createdBy: Type.Union([Type.String(), Type.Null()]),\n createdAt: Type.String(),\n updatedAt: Type.String()\n }),\n Type.Object({\n error: Type.String()\n })\n ])\n} as const satisfies RouteContract;\n\n/**\n * DELETE /cms/labels/:id - 라벨 삭제\n */\nexport const deleteLabelContract = {\n method: 'DELETE' as const,\n path: '/cms/labels/:id',\n params: Type.Object({\n id: Type.String({ description: '라벨 ID' })\n }),\n response: Type.Union([\n Type.Object({\n success: Type.Boolean(),\n id: Type.Number()\n }),\n Type.Object({\n error: Type.String()\n })\n ])\n} as const satisfies RouteContract;\n\n/**\n * GET /cms/labels/by-key/:key - Key로 라벨 조회\n */\nexport const getLabelByKeyContract = {\n method: 'GET' as const,\n path: '/cms/labels/by-key/:key',\n params: Type.Object({\n key: Type.String({ description: '라벨 Key (예: home.hero.title)' })\n }),\n response: Type.Union([\n Type.Object({\n id: Type.Number(),\n key: Type.String(),\n section: Type.String(),\n type: Type.String(),\n publishedVersion: Type.Union([Type.Number(), Type.Null()]),\n createdBy: Type.Union([Type.String(), Type.Null()]),\n createdAt: Type.String(),\n updatedAt: Type.String()\n }),\n Type.Object({\n error: Type.String(),\n key: Type.Optional(Type.String())\n })\n ])\n} as const satisfies RouteContract;"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as _sinclair_typebox from '@sinclair/typebox';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* GET /cms/published-cache
|
|
5
|
+
* 발행된 콘텐츠 캐시 조회 (단일 또는 여러 섹션)
|
|
6
|
+
*/
|
|
7
|
+
declare const getPublishedCacheContract: {
|
|
8
|
+
readonly method: "GET";
|
|
9
|
+
readonly path: "/cms/published-cache";
|
|
10
|
+
readonly query: _sinclair_typebox.TObject<{
|
|
11
|
+
sections: _sinclair_typebox.TUnion<[_sinclair_typebox.TString, _sinclair_typebox.TArray<_sinclair_typebox.TString>]>;
|
|
12
|
+
locale: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
13
|
+
}>;
|
|
14
|
+
readonly response: _sinclair_typebox.TUnion<[_sinclair_typebox.TArray<_sinclair_typebox.TObject<{
|
|
15
|
+
section: _sinclair_typebox.TString;
|
|
16
|
+
locale: _sinclair_typebox.TString;
|
|
17
|
+
content: _sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TAny>;
|
|
18
|
+
version: _sinclair_typebox.TNumber;
|
|
19
|
+
publishedAt: _sinclair_typebox.TUnion<[_sinclair_typebox.TString, _sinclair_typebox.TNull]>;
|
|
20
|
+
}>>, _sinclair_typebox.TObject<{
|
|
21
|
+
error: _sinclair_typebox.TString;
|
|
22
|
+
}>]>;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export { getPublishedCacheContract };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// src/contracts/published-cache.ts
|
|
2
|
+
import { Type } from "@sinclair/typebox";
|
|
3
|
+
var SectionData = Type.Object({
|
|
4
|
+
section: Type.String(),
|
|
5
|
+
locale: Type.String(),
|
|
6
|
+
content: Type.Record(Type.String(), Type.Any()),
|
|
7
|
+
version: Type.Number(),
|
|
8
|
+
publishedAt: Type.Union([Type.String(), Type.Null()])
|
|
9
|
+
});
|
|
10
|
+
var getPublishedCacheContract = {
|
|
11
|
+
method: "GET",
|
|
12
|
+
path: "/cms/published-cache",
|
|
13
|
+
query: Type.Object({
|
|
14
|
+
sections: Type.Union([
|
|
15
|
+
Type.String({ description: "\uB2E8\uC77C \uC139\uC158 \uC774\uB984 (\uC608: home)" }),
|
|
16
|
+
Type.Array(Type.String(), { description: '\uC5EC\uB7EC \uC139\uC158 \uC774\uB984 (\uC608: ["home", "footer"])' })
|
|
17
|
+
]),
|
|
18
|
+
locale: Type.Optional(Type.String({ default: "ko", description: "\uC5B8\uC5B4 \uCF54\uB4DC" }))
|
|
19
|
+
}),
|
|
20
|
+
response: Type.Union([
|
|
21
|
+
// 성공: 항상 배열로 반환
|
|
22
|
+
Type.Array(SectionData),
|
|
23
|
+
// 에러
|
|
24
|
+
Type.Object({
|
|
25
|
+
error: Type.String()
|
|
26
|
+
})
|
|
27
|
+
])
|
|
28
|
+
};
|
|
29
|
+
export {
|
|
30
|
+
getPublishedCacheContract
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=published-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/contracts/published-cache.ts"],"sourcesContent":["import { Type } from '@sinclair/typebox';\nimport type { RouteContract } from '@spfn/core/route';\n\nconst SectionData = Type.Object({\n section: Type.String(),\n locale: Type.String(),\n content: Type.Record(Type.String(), Type.Any()),\n version: Type.Number(),\n publishedAt: Type.Union([Type.String(), Type.Null()]),\n});\n\n/**\n * GET /cms/published-cache\n * 발행된 콘텐츠 캐시 조회 (단일 또는 여러 섹션)\n */\nexport const getPublishedCacheContract = {\n method: 'GET' as const,\n path: '/cms/published-cache',\n query: Type.Object({\n sections: Type.Union([\n Type.String({ description: '단일 섹션 이름 (예: home)' }),\n Type.Array(Type.String(), { description: '여러 섹션 이름 (예: [\"home\", \"footer\"])' })\n ]),\n locale: Type.Optional(Type.String({ default: 'ko', description: '언어 코드' })),\n }),\n response: Type.Union([\n // 성공: 항상 배열로 반환\n Type.Array(SectionData),\n // 에러\n Type.Object({\n error: Type.String()\n })\n ])\n} as const satisfies RouteContract;"],"mappings":";AAAA,SAAS,YAAY;AAGrB,IAAM,cAAc,KAAK,OAAO;AAAA,EAC5B,SAAS,KAAK,OAAO;AAAA,EACrB,QAAQ,KAAK,OAAO;AAAA,EACpB,SAAS,KAAK,OAAO,KAAK,OAAO,GAAG,KAAK,IAAI,CAAC;AAAA,EAC9C,SAAS,KAAK,OAAO;AAAA,EACrB,aAAa,KAAK,MAAM,CAAC,KAAK,OAAO,GAAG,KAAK,KAAK,CAAC,CAAC;AACxD,CAAC;AAMM,IAAM,4BAA4B;AAAA,EACrC,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,OAAO,KAAK,OAAO;AAAA,IACf,UAAU,KAAK,MAAM;AAAA,MACjB,KAAK,OAAO,EAAE,aAAa,wDAAqB,CAAC;AAAA,MACjD,KAAK,MAAM,KAAK,OAAO,GAAG,EAAE,aAAa,sEAAmC,CAAC;AAAA,IACjF,CAAC;AAAA,IACD,QAAQ,KAAK,SAAS,KAAK,OAAO,EAAE,SAAS,MAAM,aAAa,4BAAQ,CAAC,CAAC;AAAA,EAC9E,CAAC;AAAA,EACD,UAAU,KAAK,MAAM;AAAA;AAAA,IAEjB,KAAK,MAAM,WAAW;AAAA;AAAA,IAEtB,KAAK,OAAO;AAAA,MACR,OAAO,KAAK,OAAO;AAAA,IACvB,CAAC;AAAA,EACL,CAAC;AACL;","names":[]}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import * as _sinclair_typebox from '@sinclair/typebox';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* POST /cms/values/:labelId - 라벨 값 저장
|
|
5
|
+
*/
|
|
6
|
+
declare const saveValuesContract: {
|
|
7
|
+
readonly method: "POST";
|
|
8
|
+
readonly path: "/cms/values/:labelId";
|
|
9
|
+
readonly params: _sinclair_typebox.TObject<{
|
|
10
|
+
labelId: _sinclair_typebox.TString;
|
|
11
|
+
}>;
|
|
12
|
+
readonly body: _sinclair_typebox.TObject<{
|
|
13
|
+
version: _sinclair_typebox.TNumber;
|
|
14
|
+
values: _sinclair_typebox.TArray<_sinclair_typebox.TObject<{
|
|
15
|
+
locale: _sinclair_typebox.TString;
|
|
16
|
+
breakpoint: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"sm">, _sinclair_typebox.TLiteral<"md">, _sinclair_typebox.TLiteral<"lg">, _sinclair_typebox.TLiteral<"xl">, _sinclair_typebox.TLiteral<"2xl">, _sinclair_typebox.TNull]>>;
|
|
17
|
+
value: _sinclair_typebox.TObject<{
|
|
18
|
+
type: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"text">, _sinclair_typebox.TLiteral<"image">, _sinclair_typebox.TLiteral<"video">, _sinclair_typebox.TLiteral<"file">, _sinclair_typebox.TLiteral<"object">]>;
|
|
19
|
+
content: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
20
|
+
url: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
21
|
+
alt: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
22
|
+
width: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
|
|
23
|
+
height: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
|
|
24
|
+
thumbnail: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
25
|
+
duration: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
|
|
26
|
+
filename: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
27
|
+
size: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
|
|
28
|
+
fields: _sinclair_typebox.TOptional<_sinclair_typebox.TAny>;
|
|
29
|
+
}>;
|
|
30
|
+
}>>;
|
|
31
|
+
}>;
|
|
32
|
+
readonly response: _sinclair_typebox.TUnion<[_sinclair_typebox.TObject<{
|
|
33
|
+
success: _sinclair_typebox.TBoolean;
|
|
34
|
+
saved: _sinclair_typebox.TNumber;
|
|
35
|
+
version: _sinclair_typebox.TNumber;
|
|
36
|
+
}>, _sinclair_typebox.TObject<{
|
|
37
|
+
error: _sinclair_typebox.TString;
|
|
38
|
+
}>]>;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* GET /cms/values/:labelId/:version - 특정 버전의 값 조회
|
|
42
|
+
*/
|
|
43
|
+
declare const getValuesContract: {
|
|
44
|
+
readonly method: "GET";
|
|
45
|
+
readonly path: "/cms/values/:labelId/:version";
|
|
46
|
+
readonly params: _sinclair_typebox.TObject<{
|
|
47
|
+
labelId: _sinclair_typebox.TString;
|
|
48
|
+
version: _sinclair_typebox.TString;
|
|
49
|
+
}>;
|
|
50
|
+
readonly query: _sinclair_typebox.TObject<{
|
|
51
|
+
locale: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
52
|
+
breakpoint: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
53
|
+
}>;
|
|
54
|
+
readonly response: _sinclair_typebox.TUnion<[_sinclair_typebox.TObject<{
|
|
55
|
+
labelId: _sinclair_typebox.TNumber;
|
|
56
|
+
version: _sinclair_typebox.TNumber;
|
|
57
|
+
values: _sinclair_typebox.TArray<_sinclair_typebox.TObject<{
|
|
58
|
+
id: _sinclair_typebox.TNumber;
|
|
59
|
+
locale: _sinclair_typebox.TString;
|
|
60
|
+
breakpoint: _sinclair_typebox.TUnion<[_sinclair_typebox.TString, _sinclair_typebox.TNull]>;
|
|
61
|
+
value: _sinclair_typebox.TAny;
|
|
62
|
+
createdAt: _sinclair_typebox.TString;
|
|
63
|
+
}>>;
|
|
64
|
+
}>, _sinclair_typebox.TObject<{
|
|
65
|
+
error: _sinclair_typebox.TString;
|
|
66
|
+
}>]>;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export { getValuesContract, saveValuesContract };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// src/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.Number({ description: "\uBC84\uC804 \uBC88\uD638", minimum: 1 }),
|
|
40
|
+
values: Type.Array(
|
|
41
|
+
Type.Object({
|
|
42
|
+
locale: Type.String({ description: "\uC5B8\uC5B4 \uCF54\uB4DC (ko, en, ja)", default: "ko" }),
|
|
43
|
+
breakpoint: Type.Optional(Type.Union([
|
|
44
|
+
Type.Literal("sm"),
|
|
45
|
+
Type.Literal("md"),
|
|
46
|
+
Type.Literal("lg"),
|
|
47
|
+
Type.Literal("xl"),
|
|
48
|
+
Type.Literal("2xl"),
|
|
49
|
+
Type.Null()
|
|
50
|
+
], { description: "\uBC18\uC751\uD615 \uBE0C\uB808\uC774\uD06C\uD3EC\uC778\uD2B8" })),
|
|
51
|
+
value: LabelValueSchema
|
|
52
|
+
})
|
|
53
|
+
)
|
|
54
|
+
}),
|
|
55
|
+
response: Type.Union([
|
|
56
|
+
Type.Object({
|
|
57
|
+
success: Type.Boolean(),
|
|
58
|
+
saved: Type.Number(),
|
|
59
|
+
version: Type.Number()
|
|
60
|
+
}),
|
|
61
|
+
Type.Object({
|
|
62
|
+
error: Type.String()
|
|
63
|
+
})
|
|
64
|
+
])
|
|
65
|
+
};
|
|
66
|
+
var getValuesContract = {
|
|
67
|
+
method: "GET",
|
|
68
|
+
path: "/cms/values/:labelId/:version",
|
|
69
|
+
params: Type.Object({
|
|
70
|
+
labelId: Type.String({ description: "\uB77C\uBCA8 ID" }),
|
|
71
|
+
version: Type.String({ description: "\uBC84\uC804 \uBC88\uD638" })
|
|
72
|
+
}),
|
|
73
|
+
query: Type.Object({
|
|
74
|
+
locale: Type.Optional(Type.String({ description: "\uC5B8\uC5B4 \uCF54\uB4DC (ko, en, ja)" })),
|
|
75
|
+
breakpoint: Type.Optional(Type.String({ description: "\uBC18\uC751\uD615 \uBE0C\uB808\uC774\uD06C\uD3EC\uC778\uD2B8" }))
|
|
76
|
+
}),
|
|
77
|
+
response: Type.Union([
|
|
78
|
+
Type.Object({
|
|
79
|
+
labelId: Type.Number(),
|
|
80
|
+
version: Type.Number(),
|
|
81
|
+
values: Type.Array(
|
|
82
|
+
Type.Object({
|
|
83
|
+
id: Type.Number(),
|
|
84
|
+
locale: Type.String(),
|
|
85
|
+
breakpoint: Type.Union([Type.String(), Type.Null()]),
|
|
86
|
+
value: Type.Any(),
|
|
87
|
+
createdAt: Type.String()
|
|
88
|
+
})
|
|
89
|
+
)
|
|
90
|
+
}),
|
|
91
|
+
Type.Object({
|
|
92
|
+
error: Type.String()
|
|
93
|
+
})
|
|
94
|
+
])
|
|
95
|
+
};
|
|
96
|
+
export {
|
|
97
|
+
getValuesContract,
|
|
98
|
+
saveValuesContract
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=values.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/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 */\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.Number({ description: '버전 번호', minimum: 1 }),\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.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":";AAAA,SAAS,YAAY;AAMrB,IAAM,mBAAmB,KAAK,OAAO;AAAA,EACjC,MAAM,KAAK,MAAM;AAAA,IACb,KAAK,QAAQ,MAAM;AAAA,IACnB,KAAK,QAAQ,OAAO;AAAA,IACpB,KAAK,QAAQ,OAAO;AAAA,IACpB,KAAK,QAAQ,MAAM;AAAA,IACnB,KAAK,QAAQ,QAAQ;AAAA,EACzB,CAAC;AAAA,EACD,SAAS,KAAK,SAAS,KAAK,OAAO,CAAC;AAAA;AAAA,EACpC,KAAK,KAAK,SAAS,KAAK,OAAO,CAAC;AAAA;AAAA,EAChC,KAAK,KAAK,SAAS,KAAK,OAAO,CAAC;AAAA;AAAA,EAChC,OAAO,KAAK,SAAS,KAAK,OAAO,CAAC;AAAA;AAAA,EAClC,QAAQ,KAAK,SAAS,KAAK,OAAO,CAAC;AAAA;AAAA,EACnC,WAAW,KAAK,SAAS,KAAK,OAAO,CAAC;AAAA;AAAA,EACtC,UAAU,KAAK,SAAS,KAAK,OAAO,CAAC;AAAA;AAAA,EACrC,UAAU,KAAK,SAAS,KAAK,OAAO,CAAC;AAAA;AAAA,EACrC,MAAM,KAAK,SAAS,KAAK,OAAO,CAAC;AAAA;AAAA,EACjC,QAAQ,KAAK,SAAS,KAAK,IAAI,CAAC;AAAA;AACpC,CAAC;AAKM,IAAM,qBAAqB;AAAA,EAC9B,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,QAAQ,KAAK,OAAO;AAAA,IAChB,SAAS,KAAK,OAAO,EAAE,aAAa,kBAAQ,CAAC;AAAA,EACjD,CAAC;AAAA,EACD,MAAM,KAAK,OAAO;AAAA,IACd,SAAS,KAAK,OAAO,EAAE,aAAa,6BAAS,SAAS,EAAE,CAAC;AAAA,IACzD,QAAQ,KAAK;AAAA,MACT,KAAK,OAAO;AAAA,QACR,QAAQ,KAAK,OAAO,EAAE,aAAa,0CAAsB,SAAS,KAAK,CAAC;AAAA,QACxE,YAAY,KAAK,SAAS,KAAK,MAAM;AAAA,UACjC,KAAK,QAAQ,IAAI;AAAA,UACjB,KAAK,QAAQ,IAAI;AAAA,UACjB,KAAK,QAAQ,IAAI;AAAA,UACjB,KAAK,QAAQ,IAAI;AAAA,UACjB,KAAK,QAAQ,KAAK;AAAA,UAClB,KAAK,KAAK;AAAA,QACd,GAAG,EAAE,aAAa,gEAAc,CAAC,CAAC;AAAA,QAClC,OAAO;AAAA,MACX,CAAC;AAAA,IACL;AAAA,EACJ,CAAC;AAAA,EACD,UAAU,KAAK,MAAM;AAAA,IACjB,KAAK,OAAO;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,MACtB,OAAO,KAAK,OAAO;AAAA,MACnB,SAAS,KAAK,OAAO;AAAA,IACzB,CAAC;AAAA,IACD,KAAK,OAAO;AAAA,MACR,OAAO,KAAK,OAAO;AAAA,IACvB,CAAC;AAAA,EACL,CAAC;AACL;AAKO,IAAM,oBAAoB;AAAA,EAC7B,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,QAAQ,KAAK,OAAO;AAAA,IAChB,SAAS,KAAK,OAAO,EAAE,aAAa,kBAAQ,CAAC;AAAA,IAC7C,SAAS,KAAK,OAAO,EAAE,aAAa,4BAAQ,CAAC;AAAA,EACjD,CAAC;AAAA,EACD,OAAO,KAAK,OAAO;AAAA,IACf,QAAQ,KAAK,SAAS,KAAK,OAAO,EAAE,aAAa,yCAAqB,CAAC,CAAC;AAAA,IACxE,YAAY,KAAK,SAAS,KAAK,OAAO,EAAE,aAAa,gEAAc,CAAC,CAAC;AAAA,EACzE,CAAC;AAAA,EACD,UAAU,KAAK,MAAM;AAAA,IACjB,KAAK,OAAO;AAAA,MACR,SAAS,KAAK,OAAO;AAAA,MACrB,SAAS,KAAK,OAAO;AAAA,MACrB,QAAQ,KAAK;AAAA,QACT,KAAK,OAAO;AAAA,UACR,IAAI,KAAK,OAAO;AAAA,UAChB,QAAQ,KAAK,OAAO;AAAA,UACpB,YAAY,KAAK,MAAM,CAAC,KAAK,OAAO,GAAG,KAAK,KAAK,CAAC,CAAC;AAAA,UACnD,OAAO,KAAK,IAAI;AAAA,UAChB,WAAW,KAAK,OAAO;AAAA,QAC3B,CAAC;AAAA,MACL;AAAA,IACJ,CAAC;AAAA,IACD,KAAK,OAAO;AAAA,MACR,OAAO,KAAK,OAAO;AAAA,IACvB,CAAC;AAAA,EACL,CAAC;AACL;","names":[]}
|
|
@@ -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 };
|