claudeship 0.2.20 → 0.2.21
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/apps/server/dist/chat/chat.controller.d.ts +1 -1
- package/apps/server/dist/chat/chat.service.d.ts +1 -1
- package/apps/server/dist/database/database.module.js +15 -4
- package/apps/server/dist/database/database.module.js.map +1 -1
- package/apps/server/dist/database/infra/database-infra.controller.d.ts +14 -0
- package/apps/server/dist/database/infra/database-infra.controller.js +121 -0
- package/apps/server/dist/database/infra/database-infra.controller.js.map +1 -0
- package/apps/server/dist/database/infra/database-infra.service.d.ts +34 -0
- package/apps/server/dist/database/infra/database-infra.service.js +130 -0
- package/apps/server/dist/database/infra/database-infra.service.js.map +1 -0
- package/apps/server/dist/database/infra/docker.service.d.ts +34 -0
- package/apps/server/dist/database/infra/docker.service.js +186 -0
- package/apps/server/dist/database/infra/docker.service.js.map +1 -0
- package/apps/server/dist/database/infra/index.d.ts +4 -0
- package/apps/server/dist/database/infra/index.js +21 -0
- package/apps/server/dist/database/infra/index.js.map +1 -0
- package/apps/server/dist/database/infra/postgres-container.service.d.ts +31 -0
- package/apps/server/dist/database/infra/postgres-container.service.js +163 -0
- package/apps/server/dist/database/infra/postgres-container.service.js.map +1 -0
- package/apps/server/dist/database/infra/sqlite-infra.service.d.ts +14 -0
- package/apps/server/dist/database/infra/sqlite-infra.service.js +121 -0
- package/apps/server/dist/database/infra/sqlite-infra.service.js.map +1 -0
- package/apps/server/dist/project/project.controller.d.ts +7 -0
- package/apps/server/dist/project/project.module.js +2 -1
- package/apps/server/dist/project/project.module.js.map +1 -1
- package/apps/server/dist/project/project.service.d.ts +10 -1
- package/apps/server/dist/project/project.service.js +35 -3
- package/apps/server/dist/project/project.service.js.map +1 -1
- package/apps/server/dist/tsconfig.tsbuildinfo +1 -1
- package/apps/server/package.json +1 -1
- package/apps/server/prisma/dev.db +0 -0
- package/apps/server/prisma/migrations/20260109053359_add_database_provider/migration.sql +11 -0
- package/apps/server/prisma/schema.prisma +16 -5
- package/apps/web/.next/BUILD_ID +1 -1
- package/apps/web/.next/app-build-manifest.json +8 -8
- package/apps/web/.next/build-manifest.json +2 -2
- package/apps/web/.next/cache/.previewinfo +1 -1
- package/apps/web/.next/cache/.rscinfo +1 -1
- package/apps/web/.next/cache/.tsbuildinfo +1 -1
- package/apps/web/.next/cache/config.json +3 -3
- package/apps/web/.next/cache/eslint/.cache_j3uhuz +1 -1
- package/apps/web/.next/cache/webpack/client-production/0.pack +0 -0
- package/apps/web/.next/cache/webpack/client-production/index.pack +0 -0
- package/apps/web/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/apps/web/.next/cache/webpack/server-production/0.pack +0 -0
- package/apps/web/.next/cache/webpack/server-production/index.pack +0 -0
- package/apps/web/.next/prerender-manifest.json +9 -9
- package/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/apps/web/.next/server/app/_not-found.html +1 -1
- package/apps/web/.next/server/app/_not-found.rsc +2 -2
- package/apps/web/.next/server/app/index.html +1 -1
- package/apps/web/.next/server/app/index.rsc +3 -3
- package/apps/web/.next/server/app/page.js +1 -1
- package/apps/web/.next/server/app/page.js.nft.json +1 -1
- package/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/apps/web/.next/server/app/project/[id]/page.js +2 -2
- package/apps/web/.next/server/app/project/[id]/page.js.nft.json +1 -1
- package/apps/web/.next/server/app/project/[id]/page_client-reference-manifest.js +1 -1
- package/apps/web/.next/server/app/settings/page.js +2 -2
- package/apps/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/apps/web/.next/server/app/settings.html +1 -1
- package/apps/web/.next/server/app/settings.rsc +3 -3
- package/apps/web/.next/server/chunks/{811.js → 526.js} +1 -1
- package/apps/web/.next/server/pages/404.html +1 -1
- package/apps/web/.next/server/pages/500.html +1 -1
- package/apps/web/.next/server/server-reference-manifest.json +1 -1
- package/apps/web/.next/static/chunks/193-9e44b5a1ad3e0586.js +1 -0
- package/apps/web/.next/static/chunks/700-75e1212e819e279c.js +1 -0
- package/apps/web/.next/static/chunks/app/page-6f2bfb6c9202164b.js +1 -0
- package/apps/web/.next/static/chunks/app/project/[id]/page-388d14835cae411b.js +1 -0
- package/apps/web/.next/static/chunks/app/settings/page-34c4ce9b8e645903.js +1 -0
- package/apps/web/.next/static/css/70f2a13cf3d254d8.css +3 -0
- package/apps/web/.next/trace +18 -18
- package/apps/web/package.json +1 -1
- package/apps/web/src/app/settings/page.tsx +138 -2
- package/apps/web/src/components/project/ProjectCard.tsx +12 -2
- package/package.json +1 -1
- package/packages/shared/src/types/project.ts +6 -0
- package/apps/web/.next/static/chunks/87-e65fb39b36fc5ac8.js +0 -1
- package/apps/web/.next/static/chunks/992-806bad722ba16222.js +0 -1
- package/apps/web/.next/static/chunks/app/page-8310956d8eae9762.js +0 -1
- package/apps/web/.next/static/chunks/app/project/[id]/page-3d9d2622b2801ab0.js +0 -1
- package/apps/web/.next/static/chunks/app/settings/page-3532fad509d55b77.js +0 -1
- package/apps/web/.next/static/css/b92103813bcb2a3c.css +0 -3
- /package/apps/web/.next/static/{91tvQbwE6MrVEkEolpLDW → UHB0ELmeUrSRXrnycF8qv}/_buildManifest.js +0 -0
- /package/apps/web/.next/static/{91tvQbwE6MrVEkEolpLDW → UHB0ELmeUrSRXrnycF8qv}/_ssgManifest.js +0 -0
package/apps/web/package.json
CHANGED
|
@@ -4,7 +4,7 @@ import { useState, useEffect } from "react";
|
|
|
4
4
|
import { Header } from "@/components/layout/Header";
|
|
5
5
|
import { Button } from "@/components/ui/button";
|
|
6
6
|
import { Input } from "@/components/ui/input";
|
|
7
|
-
import { FolderOpen, Check, AlertCircle, Loader2 } from "lucide-react";
|
|
7
|
+
import { FolderOpen, Check, AlertCircle, Loader2, Database, RefreshCw } from "lucide-react";
|
|
8
8
|
import { api } from "@/lib/api";
|
|
9
9
|
import { useTranslation } from "@/lib/i18n";
|
|
10
10
|
|
|
@@ -12,6 +12,15 @@ interface Settings {
|
|
|
12
12
|
projectsBasePath: string;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
interface InfraStatus {
|
|
16
|
+
docker: {
|
|
17
|
+
available: boolean;
|
|
18
|
+
version?: string;
|
|
19
|
+
error?: string;
|
|
20
|
+
};
|
|
21
|
+
defaultProvider: "postgres_docker" | "sqlite";
|
|
22
|
+
}
|
|
23
|
+
|
|
15
24
|
export default function SettingsPage() {
|
|
16
25
|
const { t } = useTranslation();
|
|
17
26
|
const [settings, setSettings] = useState<Settings | null>(null);
|
|
@@ -21,8 +30,14 @@ export default function SettingsPage() {
|
|
|
21
30
|
const [error, setError] = useState<string | null>(null);
|
|
22
31
|
const [success, setSuccess] = useState(false);
|
|
23
32
|
|
|
33
|
+
// Database infrastructure state
|
|
34
|
+
const [infraStatus, setInfraStatus] = useState<InfraStatus | null>(null);
|
|
35
|
+
const [isLoadingInfra, setIsLoadingInfra] = useState(true);
|
|
36
|
+
const [isRefreshingInfra, setIsRefreshingInfra] = useState(false);
|
|
37
|
+
|
|
24
38
|
useEffect(() => {
|
|
25
39
|
loadSettings();
|
|
40
|
+
loadInfraStatus();
|
|
26
41
|
}, []);
|
|
27
42
|
|
|
28
43
|
const loadSettings = async () => {
|
|
@@ -30,13 +45,36 @@ export default function SettingsPage() {
|
|
|
30
45
|
const data = await api.get<Settings>("/settings");
|
|
31
46
|
setSettings(data);
|
|
32
47
|
setProjectsPath(data.projectsBasePath);
|
|
33
|
-
} catch
|
|
48
|
+
} catch {
|
|
34
49
|
setError("Failed to load settings");
|
|
35
50
|
} finally {
|
|
36
51
|
setIsLoading(false);
|
|
37
52
|
}
|
|
38
53
|
};
|
|
39
54
|
|
|
55
|
+
const loadInfraStatus = async () => {
|
|
56
|
+
try {
|
|
57
|
+
const data = await api.get<InfraStatus>("/database/status");
|
|
58
|
+
setInfraStatus(data);
|
|
59
|
+
} catch {
|
|
60
|
+
// Silently fail - infrastructure status is optional
|
|
61
|
+
} finally {
|
|
62
|
+
setIsLoadingInfra(false);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const refreshInfraStatus = async () => {
|
|
67
|
+
setIsRefreshingInfra(true);
|
|
68
|
+
try {
|
|
69
|
+
const data = await api.post<InfraStatus>("/database/refresh");
|
|
70
|
+
setInfraStatus(data);
|
|
71
|
+
} catch {
|
|
72
|
+
// Silently fail
|
|
73
|
+
} finally {
|
|
74
|
+
setIsRefreshingInfra(false);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
40
78
|
const handleSave = async () => {
|
|
41
79
|
setIsSaving(true);
|
|
42
80
|
setError(null);
|
|
@@ -129,6 +167,104 @@ export default function SettingsPage() {
|
|
|
129
167
|
</div>
|
|
130
168
|
)}
|
|
131
169
|
</section>
|
|
170
|
+
|
|
171
|
+
{/* Database Infrastructure */}
|
|
172
|
+
<section className="rounded-lg border bg-card p-6">
|
|
173
|
+
<div className="flex items-center justify-between mb-4">
|
|
174
|
+
<div className="flex items-center gap-3">
|
|
175
|
+
<div className="flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10">
|
|
176
|
+
<Database className="h-5 w-5 text-primary" />
|
|
177
|
+
</div>
|
|
178
|
+
<div>
|
|
179
|
+
<h2 className="text-lg font-semibold">데이터베이스 인프라</h2>
|
|
180
|
+
<p className="text-sm text-muted-foreground">
|
|
181
|
+
프로젝트별 데이터베이스 자동 관리
|
|
182
|
+
</p>
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
<Button
|
|
186
|
+
variant="ghost"
|
|
187
|
+
size="icon"
|
|
188
|
+
onClick={refreshInfraStatus}
|
|
189
|
+
disabled={isRefreshingInfra}
|
|
190
|
+
>
|
|
191
|
+
<RefreshCw className={`h-4 w-4 ${isRefreshingInfra ? "animate-spin" : ""}`} />
|
|
192
|
+
</Button>
|
|
193
|
+
</div>
|
|
194
|
+
|
|
195
|
+
{isLoadingInfra ? (
|
|
196
|
+
<div className="flex items-center justify-center py-8">
|
|
197
|
+
<Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
|
|
198
|
+
</div>
|
|
199
|
+
) : infraStatus ? (
|
|
200
|
+
<div className="space-y-4">
|
|
201
|
+
{/* Docker Status */}
|
|
202
|
+
<div className="flex items-center justify-between rounded-lg bg-muted/50 p-4">
|
|
203
|
+
<div className="flex items-center gap-3">
|
|
204
|
+
<div className={`h-3 w-3 rounded-full ${
|
|
205
|
+
infraStatus.docker.available ? "bg-green-500" : "bg-yellow-500"
|
|
206
|
+
}`} />
|
|
207
|
+
<div>
|
|
208
|
+
<p className="font-medium">Docker</p>
|
|
209
|
+
<p className="text-sm text-muted-foreground">
|
|
210
|
+
{infraStatus.docker.available
|
|
211
|
+
? `v${infraStatus.docker.version}`
|
|
212
|
+
: "설치되지 않음 또는 실행 중이 아님"}
|
|
213
|
+
</p>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
<span className={`text-sm font-medium ${
|
|
217
|
+
infraStatus.docker.available ? "text-green-600" : "text-yellow-600"
|
|
218
|
+
}`}>
|
|
219
|
+
{infraStatus.docker.available ? "실행 중" : "비활성"}
|
|
220
|
+
</span>
|
|
221
|
+
</div>
|
|
222
|
+
|
|
223
|
+
{/* Default Provider */}
|
|
224
|
+
<div className="rounded-lg bg-muted/50 p-4">
|
|
225
|
+
<p className="text-sm text-muted-foreground mb-2">기본 데이터베이스</p>
|
|
226
|
+
<div className="flex items-center gap-2">
|
|
227
|
+
{infraStatus.defaultProvider === "postgres_docker" ? (
|
|
228
|
+
<>
|
|
229
|
+
<div className="flex h-8 w-8 items-center justify-center rounded bg-blue-500/10">
|
|
230
|
+
<span className="text-xs font-bold text-blue-600">PG</span>
|
|
231
|
+
</div>
|
|
232
|
+
<div>
|
|
233
|
+
<p className="font-medium">PostgreSQL (Docker)</p>
|
|
234
|
+
<p className="text-xs text-muted-foreground">
|
|
235
|
+
프로젝트별 독립 컨테이너
|
|
236
|
+
</p>
|
|
237
|
+
</div>
|
|
238
|
+
</>
|
|
239
|
+
) : (
|
|
240
|
+
<>
|
|
241
|
+
<div className="flex h-8 w-8 items-center justify-center rounded bg-amber-500/10">
|
|
242
|
+
<span className="text-xs font-bold text-amber-600">SL</span>
|
|
243
|
+
</div>
|
|
244
|
+
<div>
|
|
245
|
+
<p className="font-medium">SQLite</p>
|
|
246
|
+
<p className="text-xs text-muted-foreground">
|
|
247
|
+
경량 파일 기반 DB (폴백)
|
|
248
|
+
</p>
|
|
249
|
+
</div>
|
|
250
|
+
</>
|
|
251
|
+
)}
|
|
252
|
+
</div>
|
|
253
|
+
</div>
|
|
254
|
+
|
|
255
|
+
{/* Info */}
|
|
256
|
+
<p className="text-xs text-muted-foreground">
|
|
257
|
+
{infraStatus.docker.available
|
|
258
|
+
? "Docker가 감지되어 새 프로젝트에 PostgreSQL이 자동으로 생성됩니다."
|
|
259
|
+
: "Docker가 없어 SQLite로 폴백됩니다. Docker를 설치하면 PostgreSQL을 사용할 수 있습니다."}
|
|
260
|
+
</p>
|
|
261
|
+
</div>
|
|
262
|
+
) : (
|
|
263
|
+
<p className="text-sm text-muted-foreground py-4">
|
|
264
|
+
인프라 상태를 불러올 수 없습니다.
|
|
265
|
+
</p>
|
|
266
|
+
)}
|
|
267
|
+
</section>
|
|
132
268
|
</div>
|
|
133
269
|
</main>
|
|
134
270
|
</div>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import Link from "next/link";
|
|
4
|
-
import { Trash2, Globe, Smartphone, Server } from "lucide-react";
|
|
4
|
+
import { Trash2, Globe, Smartphone, Server, Database } from "lucide-react";
|
|
5
5
|
import { Card } from "@/components/ui/card";
|
|
6
6
|
import { Button } from "@/components/ui/button";
|
|
7
7
|
import type { ProjectListItem } from "@claudeship/shared";
|
|
8
|
-
import { ProjectType, BackendFramework,
|
|
8
|
+
import { ProjectType, BackendFramework, DatabaseProvider } from "@claudeship/shared";
|
|
9
9
|
import { useTranslation } from "@/lib/i18n";
|
|
10
10
|
|
|
11
11
|
interface ProjectCardProps {
|
|
@@ -104,6 +104,16 @@ export function ProjectCard({ project, onDelete }: ProjectCardProps) {
|
|
|
104
104
|
{project.backendFramework === BackendFramework.EXPRESS ? "Express" : "FastAPI"}
|
|
105
105
|
</span>
|
|
106
106
|
)}
|
|
107
|
+
{project.databaseProvider && (
|
|
108
|
+
<span className={`inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-medium ${
|
|
109
|
+
project.databaseProvider === DatabaseProvider.POSTGRES_DOCKER
|
|
110
|
+
? "bg-blue-500/10 text-blue-600"
|
|
111
|
+
: "bg-amber-500/10 text-amber-600"
|
|
112
|
+
}`}>
|
|
113
|
+
<Database className="h-3 w-3" />
|
|
114
|
+
{project.databaseProvider === DatabaseProvider.POSTGRES_DOCKER ? "PostgreSQL" : "SQLite"}
|
|
115
|
+
</span>
|
|
116
|
+
)}
|
|
107
117
|
<span className="rounded-full bg-secondary px-2.5 py-0.5 text-xs text-muted-foreground">
|
|
108
118
|
{project.projectType === ProjectType.WEB ? "Web" : "Native"}
|
|
109
119
|
</span>
|
package/package.json
CHANGED
|
@@ -9,6 +9,11 @@ export enum BackendFramework {
|
|
|
9
9
|
FASTAPI = "FASTAPI",
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
export enum DatabaseProvider {
|
|
13
|
+
POSTGRES_DOCKER = "POSTGRES_DOCKER",
|
|
14
|
+
SQLITE = "SQLITE",
|
|
15
|
+
}
|
|
16
|
+
|
|
12
17
|
export const projectTypeLabels: Record<ProjectType, string> = {
|
|
13
18
|
[ProjectType.WEB]: "웹앱",
|
|
14
19
|
[ProjectType.NATIVE]: "네이티브 앱",
|
|
@@ -43,5 +48,6 @@ export interface ProjectListItem {
|
|
|
43
48
|
name: string;
|
|
44
49
|
projectType: ProjectType;
|
|
45
50
|
backendFramework: BackendFramework;
|
|
51
|
+
databaseProvider?: DatabaseProvider | null;
|
|
46
52
|
updatedAt: Date;
|
|
47
53
|
}
|