359 lines
17 KiB
Markdown
359 lines
17 KiB
Markdown
# feedback.mac.kr 커스텀 Q&A API 연동 작업 목록
|
|
|
|
## 목표
|
|
|
|
- 현재 사이트의 커스텀 Q&A 데이터를 `feedback.mac.kr` 관리 서버로 전송한다.
|
|
- 기존 `egbim/` 및 `eng/` Q&A 기능은 계속 사용할 수 있어야 한다.
|
|
- 기존 데이터는 1회 백필하고, 이후 신규 등록·수정·댓글·상태 변경·삭제를 증분 동기화한다.
|
|
- 첨부파일과 댓글 이미지는 Cloudflare R2에 저장하고, 관리 서버에는 R2 객체 정보만 전달한다.
|
|
- 관리 서버에서 Q&A 본문, 답변/댓글, 첨부파일, 작성자 정보, 상태를 일관되게 조회할 수 있도록 한다.
|
|
|
|
## 범위
|
|
|
|
### 포함
|
|
|
|
- 커스텀 Q&A 게시글: `qa_posts`
|
|
- 게시글 첨부파일: `qa_attachments`
|
|
- 댓글/답변: `qa_comments`
|
|
- 댓글 이미지와 썸네일: `qa_comment_images`
|
|
- 댓글 이미지 원본과 썸네일: R2 저장 대상
|
|
- 에디터 본문에 삽입된 이미지: R2 저장 대상
|
|
- 국문 경로: `egbim/bbs/descope_qa_*.php`
|
|
- 영문 경로: `eng/bbs/descope_qa_*.php`
|
|
|
|
### 제외
|
|
|
|
- 그누보드 기본 1:1 문의: `g5_qa_content`, `g5_qa_config`
|
|
- 쇼핑몰 상품 Q&A: `g5_shop_item_qa`
|
|
- 일반 게시판의 Q&A성 글
|
|
- FAQ 및 기타 관리자 데이터
|
|
|
|
## 현재 코드 기준 데이터 흐름
|
|
|
|
| 기능 | 현재 엔드포인트 | 저장 데이터 |
|
|
| --- | --- | --- |
|
|
| 목록 조회 | `bbs/descope_qa_list.php` | `qa_posts`, 댓글 수, 첨부 수 |
|
|
| 상세 조회 | `bbs/descope_qa_detail.php` | `qa_posts`, `qa_comments`, `qa_attachments`, `qa_comment_images` |
|
|
| 글 등록/수정 | `bbs/descope_qa_write.php` | `qa_posts`, `qa_attachments` |
|
|
| 댓글 등록 | `bbs/descope_qa_comment.php` | `qa_comments`, `qa_comment_images` |
|
|
| 댓글 수정 | `bbs/descope_qa_comment_update.php` | `qa_comments` |
|
|
| 댓글 삭제 | `bbs/descope_qa_comment_delete.php` | `qa_comments` |
|
|
| 글 상태 변경 | `bbs/descope_qa_status.php` | `qa_posts.status` |
|
|
| 글 삭제 | `bbs/descope_qa_delete.php` | 게시글·댓글·첨부 삭제 |
|
|
| 본문 이미지 업로드 | `bbs/descope_qa_img_upload.php` | 파일 시스템, 본문 URL |
|
|
|
|
## 1. 연동 정책 확정
|
|
|
|
- [ ] `feedback.mac.kr`가 데이터를 받는 방식 확정: Push API 또는 관리 서버의 Pull API
|
|
- [ ] 운영 API Base URL 및 환경별 URL 확정
|
|
- [ ] 인증 방식 확정: API Key, HMAC 서명, OAuth2 등
|
|
- [ ] API 버전과 리소스 경로 확정
|
|
- [ ] 전송 대상 사이트 구분값 확정: `ko`, `en` 또는 `egbim`, `eng`
|
|
- [ ] 관리 서버가 원본 데이터를 저장하는지, 단순 조회 프록시인지 확정
|
|
- [ ] 삭제 데이터를 실제 삭제할지 `deleted` 상태로 보존할지 확정
|
|
- [ ] 비밀글의 본문·R2 첨부파일을 관리자 서버에서 어떻게 표시할지 확정
|
|
- [ ] 개인정보 보관 기간 및 마스킹 정책 확정
|
|
|
|
### 권장 동기화 방식
|
|
|
|
- 최초 1회: 커스텀 Q&A 전체 백필
|
|
- 이후: 변경 이벤트를 동기화 큐에 기록한 뒤 API로 재시도 전송
|
|
- API 전송 성공 여부는 원본 트랜잭션과 분리해 관리
|
|
- 동일 데이터 재전송이 가능하도록 `source`, `source_id`, `event_id` 기반 멱등성 보장
|
|
|
|
## 2. 원본 데이터 구조 확인
|
|
|
|
저장소에는 커스텀 테이블의 정식 DDL이 없으므로 실제 운영 DB에서 컬럼, 타입, 인덱스, 기본값을 확인해야 한다.
|
|
|
|
- [ ] `SHOW CREATE TABLE qa_posts` 확보
|
|
- [ ] `SHOW CREATE TABLE qa_comments` 확보
|
|
- [ ] `SHOW CREATE TABLE qa_attachments` 확보
|
|
- [ ] `SHOW CREATE TABLE qa_comment_images` 확보
|
|
- [ ] 국문/영문 사이트가 동일 DB와 동일 테이블을 사용하는지 확인
|
|
- [ ] 각 테이블의 건수와 최대 ID 확인
|
|
- [ ] 고아 레코드 확인: 게시글 없는 댓글/첨부, 댓글 없는 이미지
|
|
- [ ] 실제 파일이 없는 첨부 레코드 확인
|
|
- [ ] DB의 시간대와 API 전송 시간 포맷을 `Asia/Seoul` 기준으로 통일
|
|
|
|
## 3. API 데이터 계약 설계
|
|
|
|
### 게시글 기본 필드
|
|
|
|
- [ ] `source`: `egbim` 또는 `eng`
|
|
- [ ] `source_id`: 원본 `qa_posts.post_id`
|
|
- [ ] `category`: `general`, `improvement`, `error`, `notice`, `admin`
|
|
- [ ] `title`
|
|
- [ ] `content`
|
|
- [ ] `is_secret`
|
|
- [ ] `status`: `new`, `review`, `deep`, `patch`, `done`
|
|
- [ ] `is_read_admin`
|
|
- [ ] `created_at`, `updated_at`
|
|
|
|
### 작성자 필드
|
|
|
|
- [ ] `user_id`
|
|
- [ ] `login_id`
|
|
- [ ] `user_name`
|
|
- [ ] `phone` 전송 여부 및 마스킹 방식
|
|
- [ ] `is_internal`
|
|
- [ ] `company`
|
|
- [ ] `family_company`
|
|
- [ ] `department`
|
|
- [ ] 관리자 표시명 변환 전 원본과 변환 후 표시명 중 무엇을 저장할지 결정
|
|
|
|
### 댓글/답변 필드
|
|
|
|
- [ ] `comment_id`
|
|
- [ ] 원본 게시글 ID
|
|
- [ ] `commenter`
|
|
- [ ] `user_name`
|
|
- [ ] `content`
|
|
- [ ] `created_at`, `updated_at`
|
|
- [ ] 댓글 수정·삭제 여부와 삭제 시각을 보낼 수 있도록 컬럼 또는 이벤트 구조 보완
|
|
|
|
### 첨부파일 필드
|
|
|
|
- [ ] `id` 또는 `image_id`
|
|
- [ ] 원본 게시글/댓글 ID
|
|
- [ ] `ori_name` 또는 `file_name`
|
|
- [ ] 저장 경로
|
|
- [ ] 공개 URL 또는 관리 서버용 다운로드 URL
|
|
- [ ] 파일 크기
|
|
- [ ] MIME 타입 및 확장자
|
|
- [ ] 썸네일 URL
|
|
- [ ] `uploaded_at`
|
|
- [ ] 파일 삭제 여부와 삭제 시각
|
|
- [x] 파일 저장소는 Cloudflare R2로 사용
|
|
- [ ] API에는 파일 자체를 보내지 않고 R2 객체 키·메타데이터를 보낼지 확정
|
|
- [ ] R2 공개 URL, 커스텀 도메인, presigned URL 중 접근 방식 확정
|
|
- [ ] 관리 서버가 R2에서 파일을 가져갈 수 있도록 할지, 원본 서버가 임시 URL을 발급할지 결정
|
|
|
|
## 4. API 엔드포인트 구현
|
|
|
|
### 공통 API 클라이언트
|
|
|
|
- [ ] `feedback.mac.kr` 전용 API 클라이언트 작성
|
|
- [ ] Base URL, 인증키, timeout을 환경변수로 분리
|
|
- [ ] TLS 인증서 검증 활성화
|
|
- [ ] 요청 ID와 원본 ID를 모든 요청 헤더/본문에 포함
|
|
- [ ] 연결 실패, 4xx, 5xx, timeout을 구분해 기록
|
|
- [ ] 재시도 가능한 오류와 즉시 실패해야 하는 오류 구분
|
|
- [ ] 응답 JSON 스키마 검증
|
|
- [ ] API 인증키와 개인정보가 로그에 남지 않도록 마스킹
|
|
|
|
### 권장 리소스 API
|
|
|
|
- [ ] `POST /api/v1/qna/sync` — 게시글 전체 snapshot upsert
|
|
- [ ] `POST /api/v1/qna/events` — 등록·수정·댓글·상태·삭제 이벤트 전송
|
|
- [ ] `POST /api/v1/qna/assets` — R2 객체 키와 첨부파일 메타데이터 등록
|
|
- [ ] `GET /api/v1/qna/sync/status` — 백필/증분 동기화 상태 확인
|
|
- [ ] 관리 서버의 실제 계약에 맞춰 경로와 payload 확정
|
|
|
|
## 5. 동기화 기록 및 재처리 구조
|
|
|
|
원본 저장 성공 후 API가 실패해도 사용자 작업이 실패하지 않도록 별도 동기화 기록이 필요하다.
|
|
|
|
- [ ] `qna_sync_events` 테이블 설계
|
|
- [ ] 이벤트 종류 정의: `post.created`, `post.updated`, `post.deleted`, `comment.created`, `comment.updated`, `comment.deleted`, `status.changed`, `attachment.created`, `attachment.deleted`
|
|
- [ ] 원본 테이블명과 원본 ID 저장
|
|
- [ ] payload 또는 payload 생성에 필요한 snapshot 저장
|
|
- [ ] `event_id` unique 제약으로 중복 전송 방지
|
|
- [ ] 상태 정의: `pending`, `sending`, `sent`, `failed`, `dead_letter`
|
|
- [ ] 시도 횟수, 마지막 오류, 다음 재시도 시각 저장
|
|
- [ ] 재처리용 CLI 또는 관리자 실행 도구 작성
|
|
- [ ] 일정 시간 `sending` 상태로 남은 이벤트 복구 처리
|
|
- [ ] 삭제 이벤트가 누락되지 않도록 soft-delete 또는 삭제 이력 보존
|
|
|
|
## 6. 기존 기능에 이벤트 연결
|
|
|
|
국문과 영문 코드에 같은 정책을 적용해야 한다.
|
|
|
|
- [ ] `egbim/bbs/descope_qa_write.php` 신규 등록 후 이벤트 생성
|
|
- [ ] `egbim/bbs/descope_qa_write.php` 수정 후 이벤트 생성
|
|
- [ ] `eng/bbs/descope_qa_write.php` 신규 등록 후 이벤트 생성
|
|
- [ ] `eng/bbs/descope_qa_write.php` 수정 후 이벤트 생성
|
|
- [ ] 댓글 등록 시 게시글과 댓글 이미지 이벤트 생성
|
|
- [ ] 댓글 수정 시 수정 이벤트 생성
|
|
- [ ] 댓글 삭제 시 삭제 이벤트 생성
|
|
- [ ] 게시글 상태 변경 시 상태 이벤트 생성
|
|
- [ ] 게시글 삭제 시 게시글·댓글·첨부 삭제 이벤트 순서 정의
|
|
- [ ] 에디터 이미지 업로드 시 이미지 자산 동기화 정책 적용
|
|
- [ ] 기존 화면의 저장/리다이렉트/JSON 응답 형식을 깨뜨리지 않는지 확인
|
|
|
|
### 트랜잭션 처리 원칙
|
|
|
|
- [ ] 게시글/댓글/첨부 DB 저장과 동기화 이벤트 기록은 동일 DB 트랜잭션으로 처리
|
|
- [ ] R2 업로드 성공 후 원본 DB에 객체 키를 저장
|
|
- [ ] 외부 API 호출은 원본 DB 트랜잭션 안에서 직접 실행하지 않음
|
|
- [ ] 이벤트 기록 성공 후 사용자에게 정상 응답
|
|
- [ ] 외부 API 실패는 백그라운드 재처리 대상으로 남김
|
|
- [ ] DB 저장 실패 시 이미 업로드된 R2 객체를 삭제하거나 orphan 정리 큐에 등록
|
|
|
|
## 7. 기존 데이터 백필
|
|
|
|
- [ ] 백필 기준 시각과 대상 ID 범위 확정
|
|
- [ ] `qa_posts` 전체를 페이지 단위로 추출
|
|
- [ ] 게시글별 `qa_comments` 추출
|
|
- [ ] 게시글별 `qa_attachments` 추출
|
|
- [ ] 댓글별 `qa_comment_images` 추출
|
|
- [ ] 본문 HTML에 포함된 이미지 URL 추출
|
|
- [ ] 파일 존재 여부와 파일 크기 검증
|
|
- [ ] 파일이 없는 레코드는 오류 목록으로 분리
|
|
- [ ] 원본 ID 보존형 upsert 적용
|
|
- [ ] 기존 로컬 파일을 R2로 대량 이전
|
|
- [ ] 대량 R2 업로드 속도 제한 및 실패 재시도 적용
|
|
- [ ] 백필 중 신규 변경분을 놓치지 않도록 기준 시각 이후 이벤트 재전송
|
|
- [ ] 백필 종료 후 원본 건수와 관리 서버 건수 대조
|
|
|
|
## 8. R2 첨부파일·이미지 처리
|
|
|
|
게시글 첨부파일, 댓글 이미지 원본·썸네일, 에디터 이미지를 모두 R2에 저장한다. `feedback.mac.kr` API에는 파일 바이너리 대신 R2 객체 식별자와 메타데이터를 전달하는 방향을 우선한다.
|
|
|
|
### R2 저장 구조
|
|
|
|
- [ ] R2 버킷명과 환경별 버킷 분리 여부 확정
|
|
- [ ] R2 객체 prefix 확정: 예) `qna/{source}/{post_id}/attachments/`
|
|
- [ ] 댓글 이미지 prefix 확정: 예) `qna/{source}/{post_id}/comments/{comment_id}/images/`
|
|
- [ ] 댓글 썸네일 prefix 확정: 예) `qna/{source}/{post_id}/comments/{comment_id}/thumbs/`
|
|
- [ ] 에디터 이미지 prefix 확정: 예) `qna/{source}/{post_id}/content/`
|
|
- [ ] 동일 파일 재업로드 방지를 위한 object key 또는 content hash 정책 확정
|
|
- [ ] R2 객체에 원본 파일명, MIME, 크기, source ID를 metadata로 저장
|
|
- [ ] `egbim`과 `eng` 파일의 prefix가 충돌하지 않는지 확인
|
|
|
|
### 대상별 이전·저장
|
|
|
|
- [ ] 게시글 첨부 원본 이전: `/egbim/uploads/qa/`
|
|
- [ ] 영문 게시글 첨부 원본 이전: `/eng/uploads/qa/`
|
|
- [ ] 댓글 이미지 원본 이전: `/egbim/uploads/comment/`, `/eng/uploads/comment/`
|
|
- [ ] 댓글 이미지 썸네일 이전: 각 `comment/thumb/` 경로
|
|
- [ ] 에디터 이미지 이전: `/egbim/uploads/img/`, `/eng/uploads/img/`
|
|
- [ ] 기존 DB의 `save_path`, `file_path`, `thumb_path`를 R2 object key와 연결
|
|
- [ ] 이전 완료 후에도 기존 URL을 일정 기간 유지하거나 redirect 처리
|
|
- [ ] 실제 파일이 없는 DB 레코드는 오류 목록으로 분리
|
|
- [ ] R2에만 존재하거나 DB에만 존재하는 orphan 파일 정리
|
|
|
|
### 업로드 흐름
|
|
|
|
- [ ] 신규 게시글 첨부는 R2 업로드 성공 후 `qa_attachments` 저장
|
|
- [ ] 댓글 이미지 원본과 썸네일 생성 후 R2 업로드
|
|
- [ ] `qa_comment_images`에는 R2 object key와 접근 URL 정보를 저장
|
|
- [ ] 에디터 이미지도 R2 업로드 후 본문에 최종 URL 저장
|
|
- [ ] R2 업로드 실패 시 Q&A 저장을 실패시키거나 임시 업로드로 분리할지 결정
|
|
- [ ] DB 저장 실패 시 R2 orphan 정리 작업 등록
|
|
- [ ] 파일 삭제 시 DB 삭제와 R2 객체 삭제 순서 및 재처리 정책 정의
|
|
|
|
### 접근 방식
|
|
|
|
- [ ] 공개 이미지와 비공개 첨부파일의 접근 정책 분리
|
|
- [ ] 권장안: 비밀글 첨부는 R2 비공개 저장 + 관리 서버 요청 시 짧은 presigned URL 발급
|
|
- [ ] 공개 가능한 공지 이미지 등은 R2 custom domain/CDN URL 사용 여부 결정
|
|
- [ ] API payload에는 `bucket`, `object_key`, `mime_type`, `file_size`, `original_name`, `url` 또는 `download_token` 전달
|
|
- [ ] presigned URL 만료시간과 재발급 API 정의
|
|
- [ ] 관리 서버가 원본 사이트 세션 없이도 권한 검사를 통과하는 구조인지 확인
|
|
- [ ] R2 CORS 정책에 실제 사용 Origin만 등록
|
|
- [ ] R2 lifecycle 정책: orphan 파일, 임시 업로드, 삭제 보류 파일 정리
|
|
|
|
### 코드 정리
|
|
|
|
- [ ] R2 SDK 또는 S3 호환 클라이언트 공통 모듈 작성
|
|
- [ ] R2 endpoint, access key, secret key, bucket을 환경변수로 분리
|
|
- [ ] 게시글 첨부·댓글 이미지·에디터 이미지가 같은 업로드 모듈을 사용하도록 통합
|
|
- [ ] 상대경로와 로컬 절대경로를 R2 object key로 변환하는 마이그레이션 유틸리티 작성
|
|
- [ ] 파일명 인코딩, 한글 파일명, 특수문자 처리 확인
|
|
- [ ] 허용 확장자와 MIME 타입을 원본 서버와 R2 업로드 단계에서 검증
|
|
|
|
## 9. 보안 및 개인정보
|
|
|
|
- [ ] API 인증정보를 코드에 하드코딩하지 않음
|
|
- [ ] 운영/개발/로컬 API 키 분리
|
|
- [ ] API 수신 서버 allowlist 또는 IP 제한 검토
|
|
- [ ] HMAC 사용 시 timestamp와 nonce 검증
|
|
- [ ] 재전송 공격 방지
|
|
- [ ] `phone`, `login_id`, 이메일 등 개인정보의 전송 범위 확정
|
|
- [ ] IP 주소는 기본적으로 전송하지 않거나 별도 마스킹
|
|
- [ ] 비밀글 본문과 첨부파일이 공개 URL로 노출되지 않도록 확인
|
|
- [ ] R2 access key/secret key를 코드와 API payload에 노출하지 않음
|
|
- [ ] presigned URL이 로그·DB·브라우저에 필요 이상으로 남지 않도록 만료시간 설정
|
|
- [ ] HTML 본문을 관리 서버에서 출력할 때 XSS 정화 정책 통일
|
|
- [ ] API 요청/응답 로그에서 본문·첨부 내용·개인정보를 최소화
|
|
- [ ] API 키 교체 절차와 유출 시 폐기 절차 문서화
|
|
|
|
## 10. 관측성 및 운영
|
|
|
|
- [ ] 동기화 성공/실패 건수 모니터링
|
|
- [ ] 대기 이벤트 수와 가장 오래된 대기 시간을 모니터링
|
|
- [ ] 연속 실패 시 알림 기준 설정
|
|
- [ ] `source_id`, `event_id`, `request_id`로 양쪽 로그 추적
|
|
- [ ] 백필 진행률과 실패 목록 조회 기능 제공
|
|
- [ ] API 응답 지연 및 오류율 기록
|
|
- [ ] 개인정보가 포함된 원문 로그 보관 금지
|
|
- [ ] 재처리 작업의 중복 실행 방지
|
|
|
|
## 11. 테스트 시나리오
|
|
|
|
### 기능
|
|
|
|
- [ ] 신규 게시글 등록 → 관리 서버 생성 확인
|
|
- [ ] 게시글 수정 → 관리 서버 동일 레코드 갱신 확인
|
|
- [ ] 게시글 상태 변경 → 관리 서버 상태 갱신 확인
|
|
- [ ] 댓글 등록 → 관리 서버 댓글 생성 확인
|
|
- [ ] 댓글 수정 → 관리 서버 댓글 갱신 확인
|
|
- [ ] 댓글 삭제 → 관리 서버 댓글 삭제/숨김 확인
|
|
- [ ] 게시글 첨부 등록 → 파일과 메타데이터 확인
|
|
- [ ] 댓글 이미지 등록 → 원본과 썸네일 확인
|
|
- [ ] 에디터 이미지 등록 → 본문 링크와 파일 확인
|
|
- [ ] 게시글 삭제 → 관리 서버 삭제 정책 확인
|
|
- [ ] 비밀글의 본문·첨부 권한 확인
|
|
|
|
### 장애·재처리
|
|
|
|
- [ ] 관리 서버 timeout 후 원본 저장 성공 확인
|
|
- [ ] 500 응답 후 자동 재시도 확인
|
|
- [ ] 400 응답이 무한 재시도되지 않는지 확인
|
|
- [ ] 동일 이벤트를 여러 번 보내도 중복 레코드가 생기지 않는지 확인
|
|
- [ ] API 키 오류 시 사용자 기능과 동기화 실패가 분리되는지 확인
|
|
- [ ] 이벤트 큐가 쌓인 뒤 정상 복구되는지 확인
|
|
- [ ] 삭제 직후 재전송 시 최종 상태가 일관적인지 확인
|
|
|
|
### 국문/영문
|
|
|
|
- [ ] `egbim` 신규/수정/댓글/삭제 흐름 검증
|
|
- [ ] `eng` 신규/수정/댓글/삭제 흐름 검증
|
|
- [ ] 관리 서버에서 사이트 구분이 정확한지 확인
|
|
- [ ] 같은 DB를 공유하는 경우 중복 전송이 발생하지 않는지 확인
|
|
|
|
## 12. 완료 기준
|
|
|
|
- [ ] 커스텀 Q&A 전체 데이터의 게시글·댓글·첨부·이미지가 관리 서버에서 조회됨
|
|
- [ ] 최초 백필 누락 건수가 0건이거나 승인된 예외 목록으로 관리됨
|
|
- [ ] 신규 등록·수정·댓글·상태 변경·삭제가 정해진 지연시간 내 반영됨
|
|
- [ ] API 장애가 원본 Q&A 사용을 막지 않음
|
|
- [ ] 실패 이벤트를 재처리할 수 있음
|
|
- [ ] 중복 전송에도 관리 서버 데이터가 중복되지 않음
|
|
- [ ] 비밀글과 개인정보가 정책에 맞게 보호됨
|
|
- [ ] 국문/영문 양쪽의 테스트가 완료됨
|
|
- [ ] 운영 배포 및 장애 대응 절차가 문서화됨
|
|
|
|
## 우선순위 제안
|
|
|
|
1. 관리 서버 API 계약과 인증 방식 확정
|
|
2. 네 개 커스텀 테이블의 실제 DDL/건수/파일 현황 확인
|
|
3. 동기화 이벤트 테이블과 공통 API 클라이언트 구현
|
|
4. 게시글·댓글 저장 흐름에 이벤트 기록 연결
|
|
5. R2 업로드 모듈 및 첨부파일/댓글 이미지 이전 구현
|
|
6. 기존 데이터 백필
|
|
7. 장애 재처리·모니터링·운영 배포
|
|
|
|
## 결정이 필요한 항목
|
|
|
|
- [ ] `feedback.mac.kr` API 명세 또는 수신 엔드포인트
|
|
- [ ] Push와 Pull 중 최종 방식
|
|
- [ ] API 인증 방식 및 키 발급 방법
|
|
- [ ] 게시글·댓글·첨부 삭제 보존 정책
|
|
- [ ] 개인정보 전송 필드와 마스킹 기준
|
|
- [ ] R2 버킷, prefix, public/custom domain 정책
|
|
- [ ] R2 공개 URL과 presigned URL 사용 범위
|
|
- [ ] R2 첨부파일 전송·삭제·보존 정책
|
|
- [ ] 국문/영문 데이터가 관리 서버에서 분리되어야 하는지 여부
|
|
- [ ] API 장애 시 허용 가능한 동기화 지연시간
|