데이터 연동 설정

Supabase 직접 연결 · GAS URL · 이미지 품질 옵션

우선순위: Supabase → GAS → 로컬. 대시보드 Project URL / publishable(anon) 키를 넣고 연결 테스트를 눌러 주세요.

확인 결과

URL oxvwwndnuzlbvyynouzl.supabase.co+ publishable 키 연결 성공. festivals · reviews 테이블 사용 중. specialties 테이블은 아직 없어 스토리관은 로컬/GAS 폴백입니다.

스토리관 GAS 시트 스크립트

기존 Apps Script에 붙여 넣고 specialties / applications 시트를 만들면 스토리관·입점 신청이 시트로 연결됩니다.

// === 충청이음 특산물 스토리관 시트 연동 (기존 doGet/doPost에 병합) ===
// 스프레드시트에 'specialties' 시트 헤더:
// id | name | maker | region | city | category | season | summary | story | pairings | price | image_url | featured
// 'applications' 시트 헤더:
// applied_at | business | product | region | contact | story

function handleSpecialtiesGet() {
  var sh = SpreadsheetApp.getActive().getSheetByName('specialties');
  if (!sh) return { items: [] };
  var values = sh.getDataRange().getValues();
  if (values.length < 2) return { items: [] };
  var headers = values[0].map(String);
  var items = values.slice(1).filter(function(row){ return row[0] || row[1]; }).map(function(row) {
    var o = {};
    headers.forEach(function(h, i) { o[h] = row[i]; });
    if (o.pairings && typeof o.pairings === 'string') {
      o.pairings = o.pairings.split(/[,|]/).map(function(s){ return s.trim(); }).filter(Boolean);
    }
    o.featured = o.featured === true || o.featured === 'TRUE' || o.featured === 1 || o.featured === '1';
    return o;
  });
  return { items: items };
}

function handleSpecialtyApply(body) {
  var sh = SpreadsheetApp.getActive().getSheetByName('applications');
  if (!sh) {
    sh = SpreadsheetApp.getActive().insertSheet('applications');
    sh.appendRow(['applied_at','business','product','region','contact','story']);
  }
  sh.appendRow([
    body.applied_at || new Date().toISOString(),
    body.business || '',
    body.product || '',
    body.region || '',
    body.contact || '',
    body.story || ''
  ]);
  return { ok: true };
}

// doGet: if (action === 'specialties' || action === 'stories') return json(handleSpecialtiesGet());
// doPost: if (body.action === 'specialty_apply' || body.action === 'apply') return json(handleSpecialtyApply(body));

Supabase 테이블 예시

festivals (content_id, title, start_date, end_date, addr, tel, lat, lng, image_url, source, status)

reviews (festival_id, festival_title, nickname, comment, created_at)

specialties (id, name, maker, region, city, category, season, summary, story, pairings, price, image_url, featured)

오픈채팅