galaxis-po/docs/plans/2026-02-05-phase1-foundation.md
zephyrdark d6f7d4a307 refactor: rename project from Galaxy-PO to Galaxis-Po
- Update all references in frontend, backend, and docker configs
- Update README, pyproject.toml, layout, sidebar
- Docker container names updated

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 23:24:53 +09:00

15 KiB

Phase 1: 기반 작업 구현 계획

For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

Goal: shadcn/ui, next-themes, Lucide Icons를 설치하고 다크/라이트 테마 시스템을 구축한다.

Architecture: Next.js App Router의 layout.tsx에 ThemeProvider를 적용하고, shadcn/ui의 CSS 변수 기반 테마 시스템을 사용한다. Tailwind CSS 4 환경에 맞게 설정한다.

Tech Stack: Next.js 16, React 19, Tailwind CSS 4, shadcn/ui, next-themes, lucide-react


Task 1: shadcn/ui 초기화 및 설정

Files:

  • Create: frontend/components.json
  • Create: frontend/src/lib/utils.ts
  • Modify: frontend/package.json
  • Modify: frontend/src/app/globals.css
  • Modify: frontend/tailwind.config.ts (새로 생성)

Step 1: 필수 의존성 설치

cd /home/zephyrdark/workspace/quant/galaxy-po/frontend
npm install class-variance-authority clsx tailwind-merge
npm install -D tailwindcss@latest postcss autoprefixer

Expected: 패키지 설치 완료

Step 2: tailwind.config.ts 생성

Create frontend/tailwind.config.ts:

import type { Config } from "tailwindcss";

const config: Config = {
  darkMode: ["class"],
  content: [
    "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {
      colors: {
        border: "hsl(var(--border))",
        input: "hsl(var(--input))",
        ring: "hsl(var(--ring))",
        background: "hsl(var(--background))",
        foreground: "hsl(var(--foreground))",
        primary: {
          DEFAULT: "hsl(var(--primary))",
          foreground: "hsl(var(--primary-foreground))",
        },
        secondary: {
          DEFAULT: "hsl(var(--secondary))",
          foreground: "hsl(var(--secondary-foreground))",
        },
        destructive: {
          DEFAULT: "hsl(var(--destructive))",
          foreground: "hsl(var(--destructive-foreground))",
        },
        muted: {
          DEFAULT: "hsl(var(--muted))",
          foreground: "hsl(var(--muted-foreground))",
        },
        accent: {
          DEFAULT: "hsl(var(--accent))",
          foreground: "hsl(var(--accent-foreground))",
        },
        popover: {
          DEFAULT: "hsl(var(--popover))",
          foreground: "hsl(var(--popover-foreground))",
        },
        card: {
          DEFAULT: "hsl(var(--card))",
          foreground: "hsl(var(--card-foreground))",
        },
      },
      borderRadius: {
        lg: "var(--radius)",
        md: "calc(var(--radius) - 2px)",
        sm: "calc(var(--radius) - 4px)",
      },
    },
  },
  plugins: [],
};

export default config;

Step 3: postcss.config.mjs 수정

Modify frontend/postcss.config.mjs:

const config = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
};

export default config;

Step 4: globals.css를 shadcn/ui 테마로 교체

Replace frontend/src/app/globals.css:

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  :root {
    --background: 0 0% 100%;
    --foreground: 222.2 84% 4.9%;
    --card: 0 0% 100%;
    --card-foreground: 222.2 84% 4.9%;
    --popover: 0 0% 100%;
    --popover-foreground: 222.2 84% 4.9%;
    --primary: 221.2 83.2% 53.3%;
    --primary-foreground: 210 40% 98%;
    --secondary: 210 40% 96.1%;
    --secondary-foreground: 222.2 47.4% 11.2%;
    --muted: 210 40% 96.1%;
    --muted-foreground: 215.4 16.3% 46.9%;
    --accent: 210 40% 96.1%;
    --accent-foreground: 222.2 47.4% 11.2%;
    --destructive: 0 84.2% 60.2%;
    --destructive-foreground: 210 40% 98%;
    --border: 214.3 31.8% 91.4%;
    --input: 214.3 31.8% 91.4%;
    --ring: 221.2 83.2% 53.3%;
    --radius: 0.5rem;
  }

  .dark {
    --background: 222.2 84% 4.9%;
    --foreground: 210 40% 98%;
    --card: 222.2 84% 4.9%;
    --card-foreground: 210 40% 98%;
    --popover: 222.2 84% 4.9%;
    --popover-foreground: 210 40% 98%;
    --primary: 217.2 91.2% 59.8%;
    --primary-foreground: 222.2 47.4% 11.2%;
    --secondary: 217.2 32.6% 17.5%;
    --secondary-foreground: 210 40% 98%;
    --muted: 217.2 32.6% 17.5%;
    --muted-foreground: 215 20.2% 65.1%;
    --accent: 217.2 32.6% 17.5%;
    --accent-foreground: 210 40% 98%;
    --destructive: 0 62.8% 30.6%;
    --destructive-foreground: 210 40% 98%;
    --border: 217.2 32.6% 17.5%;
    --input: 217.2 32.6% 17.5%;
    --ring: 224.3 76.3% 48%;
  }
}

@layer base {
  * {
    @apply border-border;
  }
  body {
    @apply bg-background text-foreground;
  }
}

Step 5: utils.ts 생성

Create frontend/src/lib/utils.ts:

import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

Step 6: components.json 생성

Create frontend/components.json:

{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "default",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "tailwind.config.ts",
    "css": "src/app/globals.css",
    "baseColor": "slate",
    "cssVariables": true,
    "prefix": ""
  },
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils",
    "ui": "@/components/ui",
    "lib": "@/lib",
    "hooks": "@/hooks"
  }
}

Step 7: 빌드 테스트

cd /home/zephyrdark/workspace/quant/galaxy-po/frontend
npm run build

Expected: 빌드 성공

Step 8: Commit

git add frontend/
git commit -m "feat(frontend): initialize shadcn/ui configuration

- Add tailwind.config.ts with shadcn/ui theme colors
- Update globals.css with CSS variables for dark/light mode
- Add utils.ts with cn() helper function
- Add components.json for shadcn/ui CLI"

Task 2: next-themes 설치 및 ThemeProvider 설정

Files:

  • Modify: frontend/package.json
  • Create: frontend/src/components/providers/theme-provider.tsx
  • Modify: frontend/src/app/layout.tsx

Step 1: next-themes 설치

cd /home/zephyrdark/workspace/quant/galaxy-po/frontend
npm install next-themes

Expected: 패키지 설치 완료

Step 2: ThemeProvider 컴포넌트 생성

Create frontend/src/components/providers/theme-provider.tsx:

"use client";

import * as React from "react";
import { ThemeProvider as NextThemesProvider } from "next-themes";

export function ThemeProvider({
  children,
  ...props
}: React.ComponentProps<typeof NextThemesProvider>) {
  return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
}

Step 3: layout.tsx에 ThemeProvider 적용

Modify frontend/src/app/layout.tsx:

import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import './globals.css';
import { ThemeProvider } from '@/components/providers/theme-provider';

const inter = Inter({ subsets: ['latin'] });

export const metadata: Metadata = {
  title: 'Galaxy-PO',
  description: 'Quant Portfolio Management Application',
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="ko" suppressHydrationWarning>
      <body className={inter.className}>
        <ThemeProvider
          attribute="class"
          defaultTheme="system"
          enableSystem
          disableTransitionOnChange
        >
          {children}
        </ThemeProvider>
      </body>
    </html>
  );
}

Step 4: 빌드 테스트

cd /home/zephyrdark/workspace/quant/galaxy-po/frontend
npm run build

Expected: 빌드 성공

Step 5: Commit

git add frontend/
git commit -m "feat(frontend): add next-themes for dark/light mode

- Create ThemeProvider component
- Apply ThemeProvider to root layout
- Enable system theme detection"

Task 3: Lucide Icons 설치

Files:

  • Modify: frontend/package.json

Step 1: lucide-react 설치

cd /home/zephyrdark/workspace/quant/galaxy-po/frontend
npm install lucide-react

Expected: 패키지 설치 완료

Step 2: Commit

git add frontend/package.json frontend/package-lock.json
git commit -m "feat(frontend): add lucide-react icons"

Task 4: 핵심 shadcn/ui 컴포넌트 설치

Files:

  • Create: frontend/src/components/ui/button.tsx
  • Create: frontend/src/components/ui/card.tsx
  • Create: frontend/src/components/ui/dropdown-menu.tsx
  • Create: frontend/src/components/ui/sheet.tsx
  • Create: frontend/src/components/ui/tooltip.tsx

Step 1: shadcn/ui CLI로 컴포넌트 설치

cd /home/zephyrdark/workspace/quant/galaxy-po/frontend
npx shadcn@latest add button card dropdown-menu sheet tooltip --yes

Expected: 컴포넌트 파일들이 src/components/ui/에 생성됨

Step 2: 빌드 테스트

cd /home/zephyrdark/workspace/quant/galaxy-po/frontend
npm run build

Expected: 빌드 성공

Step 3: Commit

git add frontend/
git commit -m "feat(frontend): add core shadcn/ui components

- button, card, dropdown-menu, sheet, tooltip"

Task 5: 테마 토글 컴포넌트 생성

Files:

  • Create: frontend/src/components/ui/theme-toggle.tsx

Step 1: ThemeToggle 컴포넌트 생성

Create frontend/src/components/ui/theme-toggle.tsx:

"use client";

import * as React from "react";
import { Moon, Sun } from "lucide-react";
import { useTheme } from "next-themes";

import { Button } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";

export function ThemeToggle() {
  const { setTheme } = useTheme();

  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button variant="ghost" size="icon">
          <Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
          <Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
          <span className="sr-only">테마 변경</span>
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end">
        <DropdownMenuItem onClick={() => setTheme("light")}>
          라이트
        </DropdownMenuItem>
        <DropdownMenuItem onClick={() => setTheme("dark")}>
          다크
        </DropdownMenuItem>
        <DropdownMenuItem onClick={() => setTheme("system")}>
          시스템
        </DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

Step 2: 빌드 테스트

cd /home/zephyrdark/workspace/quant/galaxy-po/frontend
npm run build

Expected: 빌드 성공

Step 3: Commit

git add frontend/src/components/ui/theme-toggle.tsx
git commit -m "feat(frontend): add ThemeToggle component

- Dropdown menu with light/dark/system options
- Uses Lucide icons for sun/moon"

Task 6: 차트 라이브러리 설치

Files:

  • Modify: frontend/package.json

Step 1: Recharts 설치

cd /home/zephyrdark/workspace/quant/galaxy-po/frontend
npm install recharts

Expected: 패키지 설치 완료

Step 2: TradingView Lightweight Charts 설치

cd /home/zephyrdark/workspace/quant/galaxy-po/frontend
npm install lightweight-charts

Expected: 패키지 설치 완료

Step 3: Commit

git add frontend/package.json frontend/package-lock.json
git commit -m "feat(frontend): add chart libraries

- recharts for general charts
- lightweight-charts for TradingView financial charts"

Task 7: 테스트 페이지로 검증

Files:

  • Modify: frontend/src/app/page.tsx (임시 수정 후 원복)

Step 1: 임시 테스트 페이지 생성

Temporarily modify frontend/src/app/page.tsx to test all components:

import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { ThemeToggle } from "@/components/ui/theme-toggle";
import { Home, Settings, User } from "lucide-react";

export default function TestPage() {
  return (
    <div className="min-h-screen p-8 bg-background text-foreground">
      <div className="max-w-4xl mx-auto space-y-8">
        <div className="flex justify-between items-center">
          <h1 className="text-3xl font-bold">Phase 1 테스트</h1>
          <ThemeToggle />
        </div>

        <Card>
          <CardHeader>
            <CardTitle>shadcn/ui 컴포넌트 테스트</CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="flex gap-2">
              <Button>Primary</Button>
              <Button variant="secondary">Secondary</Button>
              <Button variant="destructive">Destructive</Button>
              <Button variant="outline">Outline</Button>
              <Button variant="ghost">Ghost</Button>
            </div>
            <div className="flex gap-4 items-center">
              <Home className="h-6 w-6" />
              <Settings className="h-6 w-6" />
              <User className="h-6 w-6" />
              <span>Lucide Icons</span>
            </div>
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>테마 테스트</CardTitle>
          </CardHeader>
          <CardContent>
            <p className="text-muted-foreground">
              위의 테마 토글 버튼으로 라이트/다크 모드를 전환해보세요.
            </p>
          </CardContent>
        </Card>
      </div>
    </div>
  );
}

Step 2: 개발 서버 실행 및 확인

cd /home/zephyrdark/workspace/quant/galaxy-po/frontend
npm run dev

브라우저에서 http://localhost:3000 접속하여 확인:

  • 버튼들이 올바르게 렌더링되는가
  • Lucide 아이콘이 표시되는가
  • 테마 토글이 작동하는가 (라이트/다크/시스템)
  • 다크 모드에서 색상이 올바르게 변경되는가

Step 3: 테스트 완료 후 원래 페이지로 복원하지 않음

(Phase 2에서 실제 레이아웃을 구현할 때 교체 예정)

Step 4: Commit

git add frontend/src/app/page.tsx
git commit -m "test(frontend): add Phase 1 test page

- Verify shadcn/ui components render correctly
- Verify theme toggle works
- Verify Lucide icons display
- Temporary page for Phase 1 verification"

완료 체크리스트

  • Task 1: shadcn/ui 초기화 및 설정
  • Task 2: next-themes 설치 및 ThemeProvider 설정
  • Task 3: Lucide Icons 설치
  • Task 4: 핵심 shadcn/ui 컴포넌트 설치
  • Task 5: 테마 토글 컴포넌트 생성
  • Task 6: 차트 라이브러리 설치
  • Task 7: 테스트 페이지로 검증

다음 단계

Phase 1 완료 후 Phase 2 (레이아웃 컴포넌트)로 진행:

  • 새로운 Sidebar (접힘, 테마 토글, 사용자 메뉴)
  • 새로운 Header (브레드크럼, 액션 버튼)
  • 모바일 반응형 Sheet 메뉴