Add cuisine subcategory filter, fix remap logic, and add OKE deployment manifests
- Add 파인다이닝/코스 cuisine type to 한식/일식/중식/양식 categories - Change cuisine filter from flat list to grouped optgroup with subcategories - Fix remap-foods/remap-cuisine: add jdbcType=CLOB, fix CLOB LISTAGG, improve retry logic (3 attempts, batch size 5), add error logging - Add OKE deployment: Dockerfiles, K8s manifests, deploy.sh, deployment guide - Add Next.js standalone output for Docker builds Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -13,20 +13,20 @@ import MyReviewsList from "@/components/MyReviewsList";
|
||||
import BottomSheet from "@/components/BottomSheet";
|
||||
import { getCuisineIcon } from "@/lib/cuisine-icons";
|
||||
|
||||
const CUISINE_GROUPS: { label: string; prefix: string }[] = [
|
||||
{ label: "한식", prefix: "한식" },
|
||||
{ label: "일식", prefix: "일식" },
|
||||
{ label: "중식", prefix: "중식" },
|
||||
{ label: "양식", prefix: "양식" },
|
||||
{ label: "아시아", prefix: "아시아" },
|
||||
{ label: "기타", prefix: "기타" },
|
||||
const CUISINE_TAXONOMY: { category: string; items: string[] }[] = [
|
||||
{ category: "한식", items: ["백반/한정식", "국밥/해장국", "찌개/전골/탕", "삼겹살/돼지구이", "소고기/한우구이", "곱창/막창", "닭/오리구이", "족발/보쌈", "회/횟집", "해산물", "분식", "면", "죽/죽집", "순대/순대국", "장어/민물", "주점/포차", "파인다이닝/코스"] },
|
||||
{ category: "일식", items: ["스시/오마카세", "라멘", "돈카츠", "텐동/튀김", "이자카야", "야키니쿠", "카레", "소바/우동", "파인다이닝/코스"] },
|
||||
{ category: "중식", items: ["중화요리", "마라/훠궈", "딤섬/만두", "양꼬치", "파인다이닝/코스"] },
|
||||
{ category: "양식", items: ["파스타/이탈리안", "스테이크", "햄버거", "피자", "프렌치", "바베큐", "브런치", "비건/샐러드", "파인다이닝/코스"] },
|
||||
{ category: "아시아", items: ["베트남", "태국", "인도/중동", "동남아기타"] },
|
||||
{ category: "기타", items: ["치킨", "카페/디저트", "베이커리", "뷔페", "퓨전"] },
|
||||
];
|
||||
|
||||
function matchCuisineGroup(cuisineType: string | null, group: string): boolean {
|
||||
if (!cuisineType) return false;
|
||||
const g = CUISINE_GROUPS.find((g) => g.label === group);
|
||||
if (!g) return false;
|
||||
return cuisineType.startsWith(g.prefix);
|
||||
function matchCuisineFilter(cuisineType: string | null, filter: string): boolean {
|
||||
if (!cuisineType || !filter) return false;
|
||||
// filter can be a category ("한식") or full type ("한식|백반/한정식")
|
||||
if (filter.includes("|")) return cuisineType === filter;
|
||||
return cuisineType.startsWith(filter);
|
||||
}
|
||||
|
||||
const PRICE_GROUPS: { label: string; test: (p: string) => boolean }[] = [
|
||||
@@ -171,7 +171,7 @@ export default function Home() {
|
||||
const filteredRestaurants = useMemo(() => {
|
||||
return restaurants.filter((r) => {
|
||||
if (channelFilter && !(r.channels || []).includes(channelFilter)) return false;
|
||||
if (cuisineFilter && !matchCuisineGroup(r.cuisine_type, cuisineFilter)) return false;
|
||||
if (cuisineFilter && !matchCuisineFilter(r.cuisine_type, cuisineFilter)) return false;
|
||||
if (priceFilter && !matchPriceGroup(r.price_range, priceFilter)) return false;
|
||||
if (countryFilter) {
|
||||
const parsed = parseRegion(r.region);
|
||||
@@ -458,8 +458,15 @@ export default function Home() {
|
||||
className="border dark:border-gray-700 rounded-lg px-3 py-1.5 text-sm text-gray-600 dark:text-gray-300 dark:bg-gray-800"
|
||||
>
|
||||
<option value="">🍽 전체 장르</option>
|
||||
{CUISINE_GROUPS.map((g) => (
|
||||
<option key={g.label} value={g.label}>🍽 {g.label}</option>
|
||||
{CUISINE_TAXONOMY.map((g) => (
|
||||
<optgroup key={g.category} label={`── ${g.category} ──`}>
|
||||
<option value={g.category}>🍽 {g.category} 전체</option>
|
||||
{g.items.map((item) => (
|
||||
<option key={`${g.category}|${item}`} value={`${g.category}|${item}`}>
|
||||
{item}
|
||||
</option>
|
||||
))}
|
||||
</optgroup>
|
||||
))}
|
||||
</select>
|
||||
<select
|
||||
@@ -684,8 +691,15 @@ export default function Home() {
|
||||
className="border dark:border-gray-700 rounded-lg px-2.5 py-1.5 text-xs text-gray-600 dark:text-gray-300 bg-white dark:bg-gray-800"
|
||||
>
|
||||
<option value="">🍽 전체 장르</option>
|
||||
{CUISINE_GROUPS.map((g) => (
|
||||
<option key={g.label} value={g.label}>🍽 {g.label}</option>
|
||||
{CUISINE_TAXONOMY.map((g) => (
|
||||
<optgroup key={g.category} label={`── ${g.category} ──`}>
|
||||
<option value={g.category}>🍽 {g.category} 전체</option>
|
||||
{g.items.map((item) => (
|
||||
<option key={`${g.category}|${item}`} value={`${g.category}|${item}`}>
|
||||
{item}
|
||||
</option>
|
||||
))}
|
||||
</optgroup>
|
||||
))}
|
||||
</select>
|
||||
<select
|
||||
|
||||
Reference in New Issue
Block a user