별도리 Dev Docs
연동 가이드

관측 일정 (캘린더)

관측 이벤트 CRUD 및 구현 상세

엔드포인트

메서드경로설명
POST/calendar/events일정 생성
GET/calendar/events/date?date=YYYY-MM-DD날짜별 조회
GET/calendar/events/month?year=YYYY&month=M월별 요약
GET/calendar/events/{id}단건 조회
PATCH/calendar/events/{id}수정
DELETE/calendar/events/{id}삭제
POST/calendar/events/{id}/complete완료 처리
GET/calendar/events/count총 완료 관측 횟수

일정 상태 (status)

설명
PLANNED예정
COMPLETED완료 (관측 기록)
CANCELED취소

COMPLETED 상태로 직접 생성하면 endAt이 자동으로 startAt으로 설정됩니다.


이벤트 생성

POST /calendar/events
{
  "title": "M42 오리온 성운 관측",
  "startAt": "2024-01-15T20:00",
  "endAt": "2024-01-15T23:00",
  "status": "PLANNED",
  "observationSiteId": 1,
  "lat": 37.5,
  "lon": 127.0,
  "placeName": "자택 옥상",
  "memo": "망원경 80mm 사용 예정",
  "targets": ["M42", "M45"],
  "imageUrls": ["https://..."]
}
  • observationSiteId가 있으면 해당 관측지의 위경도/이름으로 자동 채움
  • targets — 관측 대상 천체 목록 (star 모듈과 연동)
  • 이미지는 이벤트당 최대 10장

완료 처리

POST /calendar/events/{id}/complete
{
  "observedAt": "2024-01-15T23:30"  // 생략 시 endAt 또는 startAt 사용
}

월별 요약

GET /calendar/events/month?year=2024&month=1

응답: 날짜별 planned / completed / canceled 건수

{
  "data": [
    { "date": "2024-01-15", "planned": 1, "completed": 0, "canceled": 0 },
    { "date": "2024-01-20", "planned": 0, "completed": 1, "canceled": 0 }
  ]
}

캘린더 UI에서 날짜 뱃지를 표시할 때 이 API를 사용합니다.


구현 상세

  • 날짜/시간은 초/나노초를 0으로 정규화해서 저장합니다. (2024-01-15T20:00:00)
  • startAtendAt보다 늦으면 400 Bad Request
  • 이벤트 삭제 시 첨부 이미지도 스토리지에서 삭제됩니다 (트랜잭션 커밋 후)

API 직접 테스트

계획/기록 작성

POST
/calendar/events

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

*/*

curl -X POST "https://byeoldori-server-hbxnfn4woa-du.a.run.app/calendar/events" \  -H "Content-Type: application/json" \  -d '{    "title": "string",    "startAt": "2019-08-24T14:15:22Z",    "status": "PLANNED"  }'
{
  "success": true,
  "message": "string",
  "data": 0
}

월별 요약

GET
/calendar/events/month

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Query Parameters

year*integer
Formatint32
month*integer
Formatint32

Response Body

*/*

curl -X GET "https://byeoldori-server-hbxnfn4woa-du.a.run.app/calendar/events/month?year=0&month=0"
{
  "success": true,
  "message": "string",
  "data": [
    {
      "date": "2019-08-24",
      "planned": 0,
      "completed": 0,
      "canceled": 0
    }
  ]
}

특정 날짜의 계획/기록 목록 조회

GET
/calendar/events/date

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Query Parameters

date*string
Formatdate

Response Body

*/*

curl -X GET "https://byeoldori-server-hbxnfn4woa-du.a.run.app/calendar/events/date?date=2019-08-24"
{
  "success": true,
  "message": "string",
  "data": [
    {
      "id": 0,
      "title": "string",
      "startAt": "2019-08-24T14:15:22Z",
      "endAt": "2019-08-24T14:15:22Z",
      "targets": [
        "string"
      ],
      "observationSiteId": 0,
      "observationSiteName": "string",
      "lat": 0.1,
      "lon": 0.1,
      "placeName": "string",
      "status": "PLANNED",
      "memo": "string",
      "photos": [
        {
          "id": 0,
          "url": "string",
          "contentType": "string"
        }
      ],
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ]
}

내 관측 횟수

GET
/calendar/events/count

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Response Body

*/*

curl -X GET "https://byeoldori-server-hbxnfn4woa-du.a.run.app/calendar/events/count"
{
  "success": true,
  "message": "string",
  "data": {
    "observationCount": 0
  }
}

단건 상세 조회

GET
/calendar/events/{id}

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

id*integer
Formatint64

Response Body

*/*

curl -X GET "https://byeoldori-server-hbxnfn4woa-du.a.run.app/calendar/events/0"
{
  "success": true,
  "message": "string",
  "data": {
    "id": 0,
    "title": "string",
    "startAt": "2019-08-24T14:15:22Z",
    "endAt": "2019-08-24T14:15:22Z",
    "targets": [
      "string"
    ],
    "observationSiteId": 0,
    "observationSiteName": "string",
    "lat": 0.1,
    "lon": 0.1,
    "placeName": "string",
    "status": "PLANNED",
    "memo": "string",
    "photos": [
      {
        "id": 0,
        "url": "string",
        "contentType": "string"
      }
    ],
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z"
  }
}

계획 및 기록 수정

PATCH
/calendar/events/{id}

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

id*integer
Formatint64

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

*/*

curl -X PATCH "https://byeoldori-server-hbxnfn4woa-du.a.run.app/calendar/events/0" \  -H "Content-Type: application/json" \  -d '{}'
{
  "success": true,
  "message": "string",
  "data": {
    "id": 0,
    "title": "string",
    "startAt": "2019-08-24T14:15:22Z",
    "endAt": "2019-08-24T14:15:22Z",
    "targets": [
      "string"
    ],
    "observationSiteId": 0,
    "observationSiteName": "string",
    "lat": 0.1,
    "lon": 0.1,
    "placeName": "string",
    "status": "PLANNED",
    "memo": "string",
    "photos": [
      {
        "id": 0,
        "url": "string",
        "contentType": "string"
      }
    ],
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z"
  }
}

계획 및 기록 삭제

DELETE
/calendar/events/{id}

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

id*integer
Formatint64

Response Body

*/*

curl -X DELETE "https://byeoldori-server-hbxnfn4woa-du.a.run.app/calendar/events/0"
{
  "success": true,
  "message": "string",
  "data": {}
}

계획 -> 완료 처리

POST
/calendar/events/{id}/complete

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

id*integer
Formatint64

Query Parameters

observedAt?string
Formatdate-time

Response Body

*/*

curl -X POST "https://byeoldori-server-hbxnfn4woa-du.a.run.app/calendar/events/0/complete"
{
  "success": true,
  "message": "string",
  "data": {
    "id": 0,
    "title": "string",
    "startAt": "2019-08-24T14:15:22Z",
    "endAt": "2019-08-24T14:15:22Z",
    "targets": [
      "string"
    ],
    "observationSiteId": 0,
    "observationSiteName": "string",
    "lat": 0.1,
    "lon": 0.1,
    "placeName": "string",
    "status": "PLANNED",
    "memo": "string",
    "photos": [
      {
        "id": 0,
        "url": "string",
        "contentType": "string"
      }
    ],
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z"
  }
}

On this page