ํ”„๋กœ์ ํŠธ๋ฐฐํฌ๋ฒ„์ „๊ด€๋ฆฌ๊ฐœ๋ฐœ์ž๋„๊ตฌ์›นํ˜ธ์ŠคํŒ…

๐Ÿš€ miri.dev ์‹ ๊ธฐ๋Šฅ: ํ”„๋กœ์ ํŠธ ๊ธฐ๋ฐ˜ ๋ฐฐํฌ ์‹œ์Šคํ…œ์œผ๋กœ ๋” ์Šค๋งˆํŠธํ•œ ์›น์‚ฌ์ดํŠธ ๊ด€๋ฆฌ

์ž‘์„ฑ์ž: miri.dev ํŒ€5๋ถ„ ์ฝ๊ธฐ

๐Ÿš€ miri.dev ์‹ ๊ธฐ๋Šฅ: ํ”„๋กœ์ ํŠธ ๊ธฐ๋ฐ˜ ๋ฐฐํฌ ์‹œ์Šคํ…œ

์•ˆ๋…•ํ•˜์„ธ์š”! miri.dev์— ๊ฒŒ์ž„ ์ฒด์ธ์ €๊ฐ€ ๋  ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค! ๐ŸŽ‰

๊ธฐ์กด์˜ ๋‹จ์ˆœํ•œ ํŒŒ์ผ ์—…๋กœ๋“œ ๋ฐฉ์‹์—์„œ ํ•œ ๋‹จ๊ณ„ ๋ฐœ์ „ํ•˜์—ฌ, ํ”„๋กœ์ ํŠธ ๊ธฐ๋ฐ˜ ๋ฐฐํฌ ์‹œ์Šคํ…œ์„ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ํ•˜๋‚˜์˜ ํ”„๋กœ์ ํŠธ์—์„œ ์—ฌ๋Ÿฌ ๋ฐฐํฌ ๋ฒ„์ „์„ ๊ด€๋ฆฌํ•˜๊ณ , ๊ณ ์ •๋œ ๋„๋ฉ”์ธ์œผ๋กœ ํ•ญ์ƒ ์ตœ์‹  ๋ฒ„์ „์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

๐ŸŽฏ ๋ฌด์—‡์ด ๋‹ฌ๋ผ์กŒ๋‚˜์š”?

๊ธฐ์กด ๋ฐฉ์‹์˜ ํ•œ๊ณ„

  • ๐Ÿ”— ์ž„์‹œ ๋„๋ฉ”์ธ: ๋ฐฐํฌํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๋žœ๋ค ๋„๋ฉ”์ธ ์ƒ์„ฑ
  • ๐Ÿ“ ๋ฒ„์ „ ๊ด€๋ฆฌ ๋ถ€์žฌ: ์ด์ „ ๋ฐฐํฌ์™€์˜ ์—ฐ๊ฒฐ์„ฑ ์—†์Œ
  • ๐Ÿ”„ ๋ถˆํŽธํ•œ ์—…๋ฐ์ดํŠธ: ์ƒˆ ๋ฐฐํฌ ์‹œ๋งˆ๋‹ค ๋„๋ฉ”์ธ์ด ๋ฐ”๋€Œ์–ด ๋งํฌ ๊ด€๋ฆฌ ์–ด๋ ค์›€
  • ๐Ÿ“Š ํ†ต๊ณ„ ๋ถ„์‚ฐ: ๋ฐฐํฌ๋ณ„๋กœ ์กฐํšŒ์ˆ˜๊ฐ€ ๋ถ„๋ฆฌ๋˜์–ด ์ „์ฒด ์„ฑ๊ณผ ํŒŒ์•… ์–ด๋ ค์›€

๐Ÿ†• ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ ์‹œ์Šคํ…œ

  • ๐ŸŒ ๊ณ ์ • ๋„๋ฉ”์ธ: project-name-12345678.miri.dev ํ˜•ํƒœ์˜ ์˜๊ตฌ ๋„๋ฉ”์ธ
  • ๐Ÿ“‹ ๋ฒ„์ „ ๊ด€๋ฆฌ: ํ•˜๋‚˜์˜ ํ”„๋กœ์ ํŠธ์— ์—ฌ๋Ÿฌ ๋ฐฐํฌ ์—ฐ๊ฒฐ ๋ฐ ์ด๋ ฅ ๊ด€๋ฆฌ
  • โšก ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ: ์ƒˆ ๋ฐฐํฌ ์‹œ ์ž๋™์œผ๋กœ ํ˜„์žฌ ๋ฒ„์ „ ๊ต์ฒด
  • ๐Ÿ“ˆ ํ†ตํ•ฉ ํ†ต๊ณ„: ํ”„๋กœ์ ํŠธ ๋‹จ์œ„๋กœ ๋ฐฐํฌ ํ˜„ํ™ฉ๊ณผ ์„ฑ๊ณผ ์ถ”์ 

๐Ÿ› ๏ธ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์ƒ์„ธ ๊ฐ€์ด๋“œ

1. ๐Ÿ“ฆ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑํ•˜๊ธฐ

๋งˆ์ดํŽ˜์ด์ง€์—์„œ "๐Ÿ“ฆ ํ”„๋กœ์ ํŠธ" ํƒญ์„ ํด๋ฆญํ•˜๊ณ  "์ƒˆ ํ”„๋กœ์ ํŠธ" ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ๋ณด์„ธ์š”!

// ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ์‹œ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ๊ตฌ์กฐ
{
  projectName: "my-portfolio",
  subdomain: "my-portfolio-a1b2c3d4",  // 8์ž๋ฆฌ ๊ณ ์œ  ID ์ถ”๊ฐ€
  domain: "my-portfolio-a1b2c3d4.miri.dev",
  deployments: [],  // ๋ฐฐํฌ ์ด๋ ฅ
  currentVersion: null  // ํ˜„์žฌ ํ™œ์„ฑ ๋ฐฐํฌ
}

ํ”„๋กœ์ ํŠธ ์ด๋ฆ„ ๊ทœ์น™:

  • โœ… ์˜๋ฌธ, ์ˆซ์ž, ํ•˜์ดํ”ˆ(-) ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • โœ… 1-50์ž ์ œํ•œ
  • โœ… ํŠน์ˆ˜๋ฌธ์ž๋Š” ์ž๋™์œผ๋กœ ํ•˜์ดํ”ˆ์œผ๋กœ ๋ณ€ํ™˜
  • โœ… 8์ž๋ฆฌ ๊ณ ์œ  ID๊ฐ€ ์ž๋™ ์ถ”๊ฐ€๋˜์–ด ์ค‘๋ณต ๋ฐฉ์ง€

2. ๐Ÿš€ ํ”„๋กœ์ ํŠธ์— ๋ฐฐํฌํ•˜๊ธฐ

๊ธฐ์กด ๋ฐฐํฌ ๋ฐฉ์‹์— ํ”„๋กœ์ ํŠธ ์—ฐ๊ฒฐ ์˜ต์…˜์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค:

์ƒˆ ํ”„๋กœ์ ํŠธ๋กœ ๋ฐฐํฌ:

// ๋ฐฐํฌ ์‹œ ํ”„๋กœ์ ํŠธ๋ช… ์ž…๋ ฅ
{
  files: [...],
  projectName: "์ƒˆ-ํ”„๋กœ์ ํŠธ๋ช…",  // ์ƒˆ ํ”„๋กœ์ ํŠธ ์ž๋™ ์ƒ์„ฑ
  deploymentNotes: "์ฒซ ๋ฒˆ์งธ ๋ฐฐํฌ"
}

๊ธฐ์กด ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€ ๋ฐฐํฌ:

// ๊ธฐ์กด ํ”„๋กœ์ ํŠธ ID๋กœ ์—ฐ๊ฒฐ
{
  files: [...],
  projectId: "abc123...",  // ๊ธฐ์กด ํ”„๋กœ์ ํŠธ ID
  deploymentNotes: "๋ฒ„๊ทธ ์ˆ˜์ • ๋ฐ ์„ฑ๋Šฅ ๊ฐœ์„ "
}

3. ๐Ÿ”„ ์ž๋™ ๋ฒ„์ „ ๊ด€๋ฆฌ

ํ”„๋กœ์ ํŠธ์— ์ƒˆ๋กœ์šด ๋ฐฐํฌ๊ฐ€ ์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค:

  1. ๋ฒ„์ „ ๋ฒˆํ˜ธ ์ž๋™ ์ฆ๊ฐ€: v1, v2, v3...
  2. ์ด์ „ ๋ฐฐํฌ ๋ณด๊ด€: ๋ชจ๋“  ๋ฐฐํฌ ์ด๋ ฅ ์œ ์ง€
  3. ํ˜„์žฌ ๋ฐฐํฌ ๊ต์ฒด: ์ƒˆ ๋ฐฐํฌ๊ฐ€ ์ž๋™์œผ๋กœ ํ™œ์„ฑํ™”
  4. ๋„๋ฉ”์ธ ์œ ์ง€: ๊ฐ™์€ ํ”„๋กœ์ ํŠธ ๋„๋ฉ”์ธ์œผ๋กœ ์ตœ์‹  ๋ฐฐํฌ ์ ‘๊ทผ
graph TD
    A[์ƒˆ ๋ฐฐํฌ ์—…๋กœ๋“œ] --> B[๋ฒ„์ „ ๋ฒˆํ˜ธ ํ• ๋‹น]
    B --> C[์ด์ „ ๋ฐฐํฌ ๋น„ํ™œ์„ฑํ™”]
    C --> D[์ƒˆ ๋ฐฐํฌ ํ™œ์„ฑํ™”]
    D --> E[ํ”„๋กœ์ ํŠธ ๋„๋ฉ”์ธ ์ž๋™ ์—ฐ๊ฒฐ]
    E --> F[์‚ฌ์šฉ์ž๋Š” ๊ฐ™์€ URL๋กœ ์ ‘๊ทผ]

๐Ÿ“ฑ ์ƒˆ๋กœ์›Œ์ง„ ๋งˆ์ดํŽ˜์ด์ง€ UI

๐ŸŽ›๏ธ ํƒญ ๊ธฐ๋ฐ˜ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ

๋งˆ์ดํŽ˜์ด์ง€๊ฐ€ ๋”์šฑ ์ง๊ด€์ ์œผ๋กœ ๊ฐœํŽธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค:

  • ๐Ÿ“„ ์‚ฌ์ดํŠธ ๋ชฉ๋ก: ๊ฐœ๋ณ„ ๋ฐฐํฌ๋“ค์„ ๊ด€๋ฆฌ
  • ๐Ÿ“ฆ ํ”„๋กœ์ ํŠธ: ํ”„๋กœ์ ํŠธ ๋‹จ์œ„๋กœ ๊ด€๋ฆฌ

๐ŸŽจ ํ–ฅ์ƒ๋œ ์‚ฌ์ดํŠธ ์นด๋“œ ๋””์ž์ธ

๊ฐ ์‚ฌ์ดํŠธ ์นด๋“œ์—์„œ ๋” ๋งŽ์€ ์ •๋ณด๋ฅผ ํ•œ๋ˆˆ์—:

interface EnhancedSiteCard {
  // ๊ธฐ๋ณธ ์ •๋ณด
  name: string;
  url: string;
  createdAt: string;
  expiresAt: string;
  
  // ๐Ÿ†• ํ”„๋กœ์ ํŠธ ์—ฐ๊ฒฐ ์ •๋ณด
  projectName?: string;
  projectDomain?: string;
  deploymentVersion?: number;
  isCurrent?: boolean;  // ํ˜„์žฌ ํ™œ์„ฑ ๋ฐฐํฌ์ธ์ง€
  deploymentNotes?: string;
  
  // ๐Ÿ†• ์—ฐ๊ฒฐ ์ƒํƒœ (์ด์ค‘ ํ™•์ธ ์‹œ์Šคํ…œ)
  connectionStatus: 'full' | 'db_only' | 'metadata_only' | 'partial';
  confidence: number;  // ๋ฐ์ดํ„ฐ ์‹ ๋ขฐ๋„ (0-100%)
}

๐ŸŽฏ ํ”„๋กœ์ ํŠธ ์นด๋“œ ์ƒˆ ๋””์ž์ธ

ํ”„๋กœ์ ํŠธ๋ณ„๋กœ ํ†ตํ•ฉ๋œ ์ •๋ณด๋ฅผ ์ œ๊ณต:

  • ๐ŸŒ ๊ณ ์ • ๋„๋ฉ”์ธ: ํด๋ฆญ ํ•œ ๋ฒˆ์œผ๋กœ ๋ฐ”๋กœ ์ ‘๊ทผ
  • ๐Ÿ“Š ๋ฐฐํฌ ํ†ต๊ณ„: ์ด ๋ฐฐํฌ ์ˆ˜, ํ™œ์„ฑ ๋ฐฐํฌ ์ˆ˜
  • ๐Ÿš€ ๋งˆ์ง€๋ง‰ ๋ฐฐํฌ: ์ตœ๊ทผ ๋ฐฐํฌ ์‹œ๊ฐ„
  • โญ ํ˜„์žฌ ๋ฒ„์ „: ํ˜„์žฌ ํ™œ์„ฑํ™”๋œ ๋ฐฐํฌ ์ •๋ณด

๐Ÿ”ง ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ๊ธฐ์ˆ ์  ์„ธ๋ถ€์‚ฌํ•ญ

๐Ÿ“ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์Šคํ‚ค๋งˆ

-- ํ”„๋กœ์ ํŠธ ํ…Œ์ด๋ธ”
CREATE TABLE projects (
  id UUID PRIMARY KEY,
  project_name TEXT NOT NULL,
  short_id VARCHAR(8) UNIQUE NOT NULL,  -- ๊ณ ์œ  8์ž๋ฆฌ ID
  subdomain TEXT UNIQUE NOT NULL,       -- project-name-shortid
  user_id TEXT NOT NULL,
  current_deployment_id UUID,           -- ํ˜„์žฌ ํ™œ์„ฑ ๋ฐฐํฌ
  created_at TIMESTAMPTZ DEFAULT now()
);

-- ํ™•์žฅ๋œ ๋ฐฐํฌ ํ…Œ์ด๋ธ”
ALTER TABLE deployed_sites ADD COLUMN
  project_id UUID,                      -- ํ”„๋กœ์ ํŠธ ์—ฐ๊ฒฐ
  deployment_version INTEGER DEFAULT 1, -- ๋ฒ„์ „ ๋ฒˆํ˜ธ
  is_current BOOLEAN DEFAULT false,     -- ํ˜„์žฌ ํ™œ์„ฑ ์—ฌ๋ถ€
  deployment_notes TEXT;                -- ๋ฐฐํฌ ๋…ธํŠธ

๐Ÿšฆ ์ž๋™ ๋ผ์šฐํŒ… ์‹œ์Šคํ…œ

๋ฏธ๋“ค์›จ์–ด์—์„œ ํ”„๋กœ์ ํŠธ ๋„๋ฉ”์ธ์„ ์ž๋™ ๊ฐ์ง€:

// ํ”„๋กœ์ ํŠธ ๋„๋ฉ”์ธ ํŒจํ„ด ๋งค์นญ
const projectDomainPattern = /^(.+)-([a-f0-9]{8})$/;

if (projectDomainPattern.test(subdomain)) {
  // ํ”„๋กœ์ ํŠธ์˜ ํ˜„์žฌ ๋ฐฐํฌ๋กœ ์ž๋™ ๋ผ์šฐํŒ…
  const currentDeployment = await getCurrentDeployment(subdomain);
  return NextResponse.rewrite(new URL(`/site/${currentDeployment.id}`, request.url));
}

๐Ÿ”„ ๋ฐฐํฌ ํ•จ์ˆ˜

ํ•ต์‹ฌ ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ ํ•จ์ˆ˜๋“ค:

-- ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ
CREATE FUNCTION create_project(
  p_project_name TEXT,
  p_user_id TEXT
) RETURNS project_info;

-- ํ”„๋กœ์ ํŠธ์— ๋ฐฐํฌ ์ถ”๊ฐ€
CREATE FUNCTION deploy_to_project(
  p_project_id UUID,
  p_site_id UUID,
  p_deployment_notes TEXT
) RETURNS BOOLEAN;

-- ํ˜„์žฌ ๋ฐฐํฌ ์กฐํšŒ
CREATE FUNCTION get_current_deployment(
  p_subdomain TEXT
) RETURNS deployment_info;

๐ŸŽฏ ์‚ฌ์šฉ ์‹œ๋‚˜๋ฆฌ์˜ค

๐Ÿ“š ๊ฐœ์ธ ํฌํŠธํด๋ฆฌ์˜ค ๊ด€๋ฆฌ

# 1. ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ
Project: "my-portfolio"
Domain: my-portfolio-a1b2c3d4.miri.dev

# 2. ์ดˆ๊ธฐ ๋ฒ„์ „ ๋ฐฐํฌ
Version: v1 (๊ธฐ๋ณธ ํฌํŠธํด๋ฆฌ์˜ค)

# 3. ๋””์ž์ธ ์—…๋ฐ์ดํŠธ
Version: v2 (์ƒˆ๋กœ์šด ํ…Œ๋งˆ ์ ์šฉ)

# 4. ํ”„๋กœ์ ํŠธ ์ถ”๊ฐ€
Version: v3 (์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ ์ถ”๊ฐ€)

# ์‚ฌ์šฉ์ž๋Š” ํ•ญ์ƒ ๊ฐ™์€ URL๋กœ ์ตœ์‹  ๋ฒ„์ „ ํ™•์ธ ๊ฐ€๋Šฅ!

๐Ÿข ํด๋ผ์ด์–ธํŠธ ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ

# ํ”„๋กœ์ ํŠธ๋ณ„๋กœ ๋ณ„๋„ ๋„๋ฉ”์ธ ๊ด€๋ฆฌ
company-website-b2c3d4e5.miri.dev  # ํšŒ์‚ฌ ์›น์‚ฌ์ดํŠธ
landing-page-c3d4e5f6.miri.dev     # ๋žœ๋”ฉํŽ˜์ด์ง€
event-site-d4e5f6g7.miri.dev       # ์ด๋ฒคํŠธ ์‚ฌ์ดํŠธ

# ๊ฐ๊ฐ ๋…๋ฆฝ์ ์ธ ๋ฐฐํฌ ์ด๋ ฅ๊ณผ ๋ฒ„์ „ ๊ด€๋ฆฌ

๐Ÿ”ฎ ์•ž์œผ๋กœ์˜ ๊ณ„ํš

Phase 1 (์™„๋ฃŒ) โœ…

  • โœ… ๊ธฐ๋ณธ ํ”„๋กœ์ ํŠธ ์‹œ์Šคํ…œ
  • โœ… ์ž๋™ ๋ผ์šฐํŒ…
  • โœ… ๋งˆ์ดํŽ˜์ด์ง€ UI ๊ฐœ์„ 

Phase 2 (์ง„ํ–‰ ์ค‘) ๐Ÿšง

  • ๐Ÿ”„ ๋ฐฐํฌ ํžˆ์Šคํ† ๋ฆฌ ์ƒ์„ธ ๋ณด๊ธฐ
  • ๐Ÿ”„ ํ”„๋กœ์ ํŠธ ์„ค์ • ๊ด€๋ฆฌ
  • ๐Ÿ”„ ์ปค์Šคํ…€ ๋„๋ฉ”์ธ ์—ฐ๊ฒฐ

Phase 3 (๊ณ„ํš) ๐Ÿ“‹

  • ๐Ÿ“‹ Git ์ €์žฅ์†Œ ์—ฐ๋™
  • ๐Ÿ“‹ ์›นํ›… ๊ธฐ๋ฐ˜ ์ž๋™ ๋ฐฐํฌ
  • ๐Ÿ“‹ ํ™˜๊ฒฝ๋ณ„ ๋ฐฐํฌ (dev/staging/prod)
  • ๐Ÿ“‹ ํ˜‘์—… ๊ธฐ๋Šฅ (ํŒ€ ๋ฉค๋ฒ„ ์ดˆ๋Œ€)

Phase 4 (๋ฏธ๋ž˜) ๐ŸŒŸ

  • ๐ŸŒŸ CI/CD ํŒŒ์ดํ”„๋ผ์ธ ์—ฐ๋™
  • ๐ŸŒŸ A/B ํ…Œ์ŠคํŠธ ์ง€์›
  • ๐ŸŒŸ ์‹ค์‹œ๊ฐ„ ๋ถ„์„ ๋Œ€์‹œ๋ณด๋“œ
  • ๐ŸŒŸ ๋ชจ๋ฐ”์ผ ์•ฑ ๋ฐฐํฌ ์ง€์›

๐ŸŽ‰ ์ง€๊ธˆ ๋ฐ”๋กœ ์ฒดํ—˜ํ•ด๋ณด์„ธ์š”!

  1. miri.dev ์ ‘์†
  2. ์นด์นด์˜ค/๋„ค์ด๋ฒ„ ๋กœ๊ทธ์ธ ํ›„ ๋งˆ์ดํŽ˜์ด์ง€ ์ด๋™
  3. "๐Ÿ“ฆ ํ”„๋กœ์ ํŠธ" ํƒญ์—์„œ ์ฒซ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ
  4. ํŒŒ์ผ ์—…๋กœ๋“œ ์‹œ ํ”„๋กœ์ ํŠธ ์—ฐ๊ฒฐ ์„ ํƒ
  5. ๊ณ ์ • ๋„๋ฉ”์ธ์œผ๋กœ ๋ฐ”๋กœ ํ™•์ธ!

๐Ÿ’ฌ ํ”ผ๋“œ๋ฐฑ์„ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค

์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ ์‹œ์Šคํ…œ์ด ์–ด๋– ์‹ ๊ฐ€์š”?

์—ฌ๋Ÿฌ๋ถ„์˜ ์†Œ์ค‘ํ•œ ์˜๊ฒฌ์œผ๋กœ miri.dev๊ฐ€ ๋”์šฑ ๋ฐœ์ „ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ๐Ÿš€


miri.dev์™€ ํ•จ๊ป˜ ๋” ์Šค๋งˆํŠธํ•œ ์›น ๊ฐœ๋ฐœ์„ ๊ฒฝํ—˜ํ•ด๋ณด์„ธ์š”! ๐Ÿ’ปโœจ