INSERT, UPDATE, DELETE가 일어날 때supabase.rpc('function_name') 형태로 호출DB 함수(=프로시저) 는 로직의 본체,
트리거는 그걸 자동으로 실행하는 장치,
RPC는 DB 함수를 외부에서 API처럼 호출하는 통로,
RLS는 접근을 제한하는 보안 규칙,
Edge Function은 DB 밖에서 돌아가는 확장 로직이다.

https://api.slack.com/apps/
create new app -> from a manifest -> select a workspace 해서 새 app 생성
app home -> Your App’s Presence in Slack에서 이름 바꿀 수 있음
OAuth & Permissions -> scope에서 chat:write 권한 추가, OAuth Tokens에서 install to 워크스페이스
이러면 Bot User OAuth Token 보일거임
supabase에서 bot token 사용해서 알림 보내는 트리거 함수를 edge function에 등록
settings -> edge functions -> secres에서 bot token 등록
(로컬에서 테스트할 땐 환경변수에 저장)
후술하지만 다른 방식도 있습니다
slack oicd 연동해뒀으면 Authentication에 Sign In / Providers 쪽에 slack oicd가 enabled되어 있을텐데... 봇을 쓴다고 해서 client id랑 client secret을 전부 바꿀 필요는 없는듯? 워크스페이스가 다를 때만 의미가 있는 것 같음
| 방식 | 장점 | 단점 | 선택 여부 |
|---|---|---|---|
| Next.js API + 외부 cron | 코드베이스 통합 | 별도 서버/스케줄러 필요 | ❌ |
| 컨테이너 내부 cron | 간단 | Dockerfile 수정, 권장하지 않음 | ❌ |
| Edge Function + pg_cron | 인프라 불필요, Supabase가 실행 | - | ✅ |
더 자세히 보면
| 항목 | 컨테이너 cron | Next.js API + 외부 cron | pg_cron (현재) |
|---|---|---|---|
| 설정 복잡도 | 중간 (Dockerfile 수정) | 중간 (API Route + 외부 서비스) | 낮음 (SQL만) |
| 안정성 | 낮음 (컨테이너 의존) | 중간 (외부 서비스 의존) | 높음 (DB 레벨) |
| 스케일링 | 문제 있음 (중복 실행) | 문제 있음 (외부 호출 중복 가능) | 문제 없음 |
| 로그 관리 | 어려움 | 중간 (Next.js 로그) | 쉬움 (DB 쿼리) |
| 재시작 영향 | 있음 | 없음 (외부 호출) | 없음 |
| 인프라 의존성 | 컨테이너 | 외부 cron 서비스 | Supabase |
| 비용 | 없음 | 무료/유료 서비스 | 없음 |
| 보안 | 내부 | 외부 HTTP 노출 | 내부 |
| 실행 이력 추적 | 어려움 | 외부 서비스에 의존 | 쉬움 (DB 쿼리) |
형상 관리가 어려워서 좀 복잡해지는 한이 있더라도 codebase로 옮기는 추세
slack 알림 연동 기능을 처음엔 edge function으로 작성했으나 코드로 마이그레이션 했음
gemini 코드 리뷰에서 원자성 보장을 위해 db function쓰는거 생각해보라 했지만
최대한 서버액션으로 처리하는걸로 결정
그러나... 주기적 알림을 추가 인프라를 만지지 않고 구현하려다보니
pg_cron을 사용하게 되면서 edge function을 다시 쓰게 되긴 했다
직접 사이트에서 edge function을 deploy해왔었는데 구글링하다가 발견..
공식 문서를 잘 읽읍시다
https://supabase.com/docs/guides/functions/deploy
post 401 에러에 마주쳤는데 이건 jwt 인증 끄고 해결..?
https://github.com/orgs/supabase/discussions/33194
이건 좀 위험하다해서 cron secret을 헤더에 추가해서 검증...?
사실 이해가 좀 덜 되긴 했다.
sql문 지금까지 실행하면서 policy / db함수 / edge function 만든 거 다시봐야될 것 같다.
SELECT cron.schedule(
'check-reminders',
'*/5 * * * *', -- 매 5분마다
$$
SELECT
net.http_post(
url := 'https://프로젝트코드.supabase.co/functions/v1/함수이름',
headers := jsonb_build_object(
'Content-Type', 'application/json',
'x-cron-secret', '임의의 값'
),
body := '{}'::jsonb
) AS request_id;
$$
);