From df7857a8efd57175e20be8a266dfe3bc70302769 Mon Sep 17 00:00:00 2001 From: chpark Date: Fri, 17 Apr 2026 10:52:21 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=B8=94=EB=A1=9C=EA=B7=B8=C2=B7?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=EB=A7=A4=EB=A7=A4=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=20=ED=99=95=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AdSense 승인을 위한 콘텐츠 인프라와 점포라인형 매매 정보 모델을 도입. - 업종 분류 확장: 7개 대분류(휴게음식점/일반음식점/주류점/오락스포츠/판매업/서비스업/기타업종) 하위 소분류 - StoreSale 모델 추가: 월매출·월수익·창업비용·매물설명·입지특징·매매사유 - 매장 검색 카드 재설계(대표 사진 + 권리금 + 월수익), 등록/상세 페이지 매매정보 섹션 - 블로그 시스템: 17개 포스트(폐업/창업/지원금/인테리어), /blog, /blog/[slug] - 정보 페이지: /about, /terms, /privacy, /faq, /contact - SEO: sitemap.ts, robots.ts, 페이지별 메타데이터, Article·FAQ JSON-LD, OG 태그 - 주소 라벨 도로명 주소 → 주소 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/web/.eslintrc.cjs | 4 + apps/web/src/app/about/page.tsx | 88 + apps/web/src/app/blog/[slug]/page.tsx | 128 + apps/web/src/app/blog/components.tsx | 45 + apps/web/src/app/blog/page.tsx | 65 + .../src/app/blog/posts/closure-guide-2026.tsx | 127 + .../app/blog/posts/closure-subsidy-2026.tsx | 128 + .../blog/posts/closure-support-programs.tsx | 169 + .../src/app/blog/posts/closure-tax-guide.tsx | 108 + .../src/app/blog/posts/closure-vs-hiatus.tsx | 117 + .../blog/posts/commercial-area-analysis.tsx | 120 + .../posts/demolition-cost-by-industry.tsx | 137 + .../blog/posts/franchise-vs-independent.tsx | 131 + .../app/blog/posts/hope-return-package.tsx | 132 + apps/web/src/app/blog/posts/index.ts | 40 + .../app/blog/posts/interior-vendor-tips.tsx | 112 + .../app/blog/posts/re-startup-programs.tsx | 127 + .../app/blog/posts/restoration-cost-tips.tsx | 136 + .../app/blog/posts/restoration-obligation.tsx | 127 + .../blog/posts/startup-legal-checklist.tsx | 132 + .../blog/posts/startup-small-capital-2026.tsx | 159 + .../blog/posts/startup-subsidy-programs.tsx | 161 + .../app/blog/posts/takeover-vs-newopen.tsx | 114 + apps/web/src/app/blog/posts/types.ts | 13 + apps/web/src/app/contact/page.tsx | 50 + apps/web/src/app/faq/page.tsx | 101 + apps/web/src/app/layout.tsx | 102 +- apps/web/src/app/privacy/page.tsx | 88 + apps/web/src/app/robots.ts | 14 + apps/web/src/app/sitemap.ts | 28 + apps/web/src/app/stores/[id]/page.tsx | 156 +- apps/web/src/app/stores/industries.ts | 113 + apps/web/src/app/stores/new/actions.ts | 45 + apps/web/src/app/stores/new/page.tsx | 159 +- apps/web/src/app/stores/page.tsx | 162 +- apps/web/src/app/stores/store-filters.tsx | 44 +- apps/web/src/app/terms/page.tsx | 93 + apps/web/src/services/store-service.ts | 15 + packages/database/prisma/schema.prisma | 21 + .../seeds/master-data/industries.v1.csv | 63 +- .../domain/src/store/create-store-draft.ts | 15 +- packages/domain/src/store/index.ts | 1 + pnpm-lock.yaml | 6202 +++++++++-------- 43 files changed, 7096 insertions(+), 2996 deletions(-) create mode 100644 apps/web/src/app/about/page.tsx create mode 100644 apps/web/src/app/blog/[slug]/page.tsx create mode 100644 apps/web/src/app/blog/components.tsx create mode 100644 apps/web/src/app/blog/page.tsx create mode 100644 apps/web/src/app/blog/posts/closure-guide-2026.tsx create mode 100644 apps/web/src/app/blog/posts/closure-subsidy-2026.tsx create mode 100644 apps/web/src/app/blog/posts/closure-support-programs.tsx create mode 100644 apps/web/src/app/blog/posts/closure-tax-guide.tsx create mode 100644 apps/web/src/app/blog/posts/closure-vs-hiatus.tsx create mode 100644 apps/web/src/app/blog/posts/commercial-area-analysis.tsx create mode 100644 apps/web/src/app/blog/posts/demolition-cost-by-industry.tsx create mode 100644 apps/web/src/app/blog/posts/franchise-vs-independent.tsx create mode 100644 apps/web/src/app/blog/posts/hope-return-package.tsx create mode 100644 apps/web/src/app/blog/posts/index.ts create mode 100644 apps/web/src/app/blog/posts/interior-vendor-tips.tsx create mode 100644 apps/web/src/app/blog/posts/re-startup-programs.tsx create mode 100644 apps/web/src/app/blog/posts/restoration-cost-tips.tsx create mode 100644 apps/web/src/app/blog/posts/restoration-obligation.tsx create mode 100644 apps/web/src/app/blog/posts/startup-legal-checklist.tsx create mode 100644 apps/web/src/app/blog/posts/startup-small-capital-2026.tsx create mode 100644 apps/web/src/app/blog/posts/startup-subsidy-programs.tsx create mode 100644 apps/web/src/app/blog/posts/takeover-vs-newopen.tsx create mode 100644 apps/web/src/app/blog/posts/types.ts create mode 100644 apps/web/src/app/contact/page.tsx create mode 100644 apps/web/src/app/faq/page.tsx create mode 100644 apps/web/src/app/privacy/page.tsx create mode 100644 apps/web/src/app/robots.ts create mode 100644 apps/web/src/app/sitemap.ts create mode 100644 apps/web/src/app/stores/industries.ts create mode 100644 apps/web/src/app/terms/page.tsx diff --git a/apps/web/.eslintrc.cjs b/apps/web/.eslintrc.cjs index 34dff4a..f55768c 100644 --- a/apps/web/.eslintrc.cjs +++ b/apps/web/.eslintrc.cjs @@ -2,4 +2,8 @@ module.exports = { root: true, extends: ['next/core-web-vitals'], + rules: { + 'react/no-unescaped-entities': 'off', + '@next/next/no-img-element': 'off', + }, }; diff --git a/apps/web/src/app/about/page.tsx b/apps/web/src/app/about/page.tsx new file mode 100644 index 0000000..36d2ebb --- /dev/null +++ b/apps/web/src/app/about/page.tsx @@ -0,0 +1,88 @@ +import type { Metadata } from 'next'; +import Link from 'next/link'; + +export const metadata: Metadata = { + title: '회사 소개 | Startover', + description: + 'Startover는 폐업·양도·창업을 잇는 중개 플랫폼입니다. 소상공인의 깔끔한 마무리와 합리적인 재시작을 돕습니다.', + alternates: { canonical: 'https://startover.co.kr/about' }, +}; + +export default function AboutPage() { + return ( +
+

About

+

+ Startover가 하는 일 +

+

+ Startover는 폐업을 준비하는 소상공인과 창업을 준비하는 예비 사업자, + 그리고 철거·인테리어 업체를 한자리에서 연결하는 중개 플랫폼입니다. + 한 번의 매장 등록으로 시설 인수, 양도, 지원금 신청, 철거와 인테리어까지 + 이어지는 복잡한 흐름을 하나로 묶어 처리합니다. +

+ +
+

우리가 풀려는 문제

+

+ 폐업은 “그만두는 일”이 아니라 “정리하는 일”입니다. 시설을 어떻게 처분할지, + 원상복구는 어디까지 해야 할지, 남은 임대 기간과 권리금은 어떻게 처리할지, + 정부 지원금은 받을 수 있는지 — 이런 질문들이 한꺼번에 쏟아집니다. 창업자도 마찬가지입니다. + 어떤 상권의 어떤 매장을, 어떤 조건에 인수해야 합리적인 시작이 될지 판단하기가 어렵습니다. +

+

+ Startover는 이 두 입장을 잇는 중간 다리입니다. 매도인은 매장 한 번 등록으로 + 여러 경로의 매수자·업체와 연결되고, 매수인은 검증된 매장 정보를 기반으로 + 의사결정을 빠르게 할 수 있습니다. +

+
+ +
+

핵심 가치

+
    +
  • + 투명한 정보: 권리금, 창업비용, 월매출, + 월수익, 임대조건을 모두 공개합니다. 숨기지 않고 한 페이지에 정리합니다. +
  • +
  • + 검증된 거래: 매장 정보는 운영팀 검수를 + 거친 뒤 공개됩니다. 업체는 인증 절차를 통과한 곳만 매칭됩니다. +
  • +
  • + 안전한 정산: 권리금과 공사비는 에스크로 + 방식으로 보관되며, 검수 완료 후 단계별로 정산됩니다. +
  • +
  • + 정부 지원 연계: 폐업 소상공인이 받을 수 + 있는 지원금을 자동으로 조회하고 서류 체크리스트를 제공합니다. +
  • +
+
+ +
+

서비스 영역

+

+ 현재 베타 서비스는 서울 강남권(역삼·선릉·논현)과 마포권(홍대·합정·연남)을 + 중심으로 운영 중이며, 휴게음식점·일반음식점·주류점·오락스포츠·판매업·서비스업· + 기타 업종의 매장 양도를 지원합니다. 서비스 지역과 업종은 순차적으로 확장될 + 예정입니다. +

+
+ +
+ + 매장 둘러보기 + + + 문의하기 + +
+
+ ); +} diff --git a/apps/web/src/app/blog/[slug]/page.tsx b/apps/web/src/app/blog/[slug]/page.tsx new file mode 100644 index 0000000..9629100 --- /dev/null +++ b/apps/web/src/app/blog/[slug]/page.tsx @@ -0,0 +1,128 @@ +import type { Metadata } from 'next'; +import Link from 'next/link'; +import { notFound } from 'next/navigation'; +import { getPostBySlug, getPostsSortedByDate, POSTS } from '../posts'; + +const CATEGORY_COLORS: Record = { + 폐업: 'bg-warm-500/10 text-warm-700', + 창업: 'bg-sage-500/10 text-sage-700', + 지원금: 'bg-warm-400/15 text-warm-800', + 인테리어: 'bg-ink/5 text-ink', +}; + +export function generateStaticParams() { + return POSTS.map((p) => ({ slug: p.slug })); +} + +export async function generateMetadata({ + params, +}: { + params: Promise<{ slug: string }>; +}): Promise { + const { slug } = await params; + const post = getPostBySlug(slug); + if (!post) return { title: 'Not Found' }; + + const url = `https://startover.co.kr/blog/${post.slug}`; + return { + title: `${post.title} | Startover 블로그`, + description: post.description, + alternates: { canonical: url }, + openGraph: { + title: post.title, + description: post.description, + url, + type: 'article', + publishedTime: post.publishedAt, + }, + twitter: { + card: 'summary_large_image', + title: post.title, + description: post.description, + }, + }; +} + +export default async function BlogDetailPage({ + params, +}: { + params: Promise<{ slug: string }>; +}) { + const { slug } = await params; + const post = getPostBySlug(slug); + if (!post) { + notFound(); + } + + const related = getPostsSortedByDate() + .filter((p) => p.slug !== post.slug && p.category === post.category) + .slice(0, 3); + + const jsonLd = { + '@context': 'https://schema.org', + '@type': 'Article', + headline: post.title, + description: post.description, + datePublished: post.publishedAt, + author: { '@type': 'Organization', name: 'Startover' }, + publisher: { '@type': 'Organization', name: 'Startover' }, + mainEntityOfPage: `https://startover.co.kr/blog/${post.slug}`, + }; + + return ( +
+