1.변경 집합 개발 모델에서 유효성 검사를 진행할 때 발생하던 종속성 문제 등이 자주 발견되자

모든 하위 변경사항들을 추적하기를 원하게 되었고

VS Code용 Salesforce 확장을 사용하여 개발 환경에서 메타데이터를 검색하기를 원했다.

 

해당 문제들은 아래와 같은 도구들을 사용해 문제를 해결할 수 있다.

Tool Description
Change list 개발자는 이 간단한 목록, 표 또는 스프레드시트를 사용하여 자신의 개발 조직에서 변경한 사항을 추적하므로 무엇을 구체화해야 하는지 알 수 있다.
Deployment run list 배포 전후에 조직에 필요한 모든 수동 변경 사항(메타 데이터)를 나열한다.
Project management tools Agile Accelerator 및 Jira와 같은 도구는 팀이 Agile 개발 사례를 수용하고 비즈니스 요구 사항, 기능 작업 및 버그를 추적하는데 도움이 된다.

 

 

2.변경 집합 개발 모델을 사용할 경우 릴리즈 계획을 작성해야 하며

릴리즈 환경은 개발, 테스트, 릴리즈 빌드, 릴리즈 테스트, 릴리즈 단계로 나뉜다.

 

setup에서 Sandboxes로 들어가 new Sandboxes를 생성한 다음

developer 유형을 선택해 start copy로 생성할 경우 조직 사본을 생성할 수 있다.

 

developer.salesforce.com/docs/metadata-coverage에서 메타데이터 적용 범위 보고서에 엑세스 할 수 있다.

 

 

3.맞춤형 객체를 만들기 위해서는 sandbox에 로그인 한 다음 개체 관리자 탭에서 생성할 수 있고

필드 또한 기존과 유사하게 객체를 선택한 다음 필드를 추가 및 수정할 수 있다.

 

 

4.변경 집합을 승인하기 위해서는 연결을 승인해야 하는데 해당 작업은

Deployment Settings에 들어가 인바운드 변경 집합을 수신할 조직을 추가하고

인바운드 변경 허용을 선택 후 저장하면 sandbox에서 업로드된 모든 변경 집합이 허용된다.

 

 

5.유효성 검사를 통해 배포의 예비 실행을 해볼 수 있는데

유효성 검사의 실패 중 가장 자주 발견되는 문제는 종속성 구성 요소 관련이다.

 

새로 생성한 sandbox에서 생성한 객체 또는 관계에 대한 추가가 없으면 배포는 실패하게 된다.

 

 

6.표기 타입, 주소, 언어,시간대 등을 설정하기 위해서는

Setup의 Company Information에 들어가서 할 수 있고

개인 설정 부분은 profile을 누르고 settings에 들어가

Language & Time Zone 부분을 수정하면 된다.

 

 

7.다중 통화 설정 또한 Company Information에서 진행할 수 있는데

Activate Multiple Currencies를 활성화 할 경우

새 기업 통화 선택, 사용자 개인 통화 유효성 체크, 레코드 생성시 통화 유효성 체크 등이 가능해진다.

 

또한 고급 통화 기능 활성화를 통해 특정 날짜의 통화 비율을 관리할 수 있기 때문에

정확한 가치를 더 정확하게 비교할 수 있다.

 

 

8.사용자 지정 메타데이터는 매핑, 비즈니스 규칙, 기본 데이터, 보호된 정보 등에 사용한다.

 

mapping - 서로 다른 개체 간의 연결을 생성하는 메다테이터 유형을 생성할 수 있다.

비즈니스 규칙 - 사용자 지정 기능과 레코드를 결합해 결제 시스템 등에 사용할 수 있다.

기본 데이터 - 사용자 정의 메타데이터에서 참조해서 회계, 관세 등을 계산할 수 있다.

보호된 정보 - API 키와 같은 데이터를 보호된 패키지에 저장

 

메타데이터는 관계, 체크박스, 날짜, 시간, 이메일, 전화, 숫자, 퍼센트, picklist, 텍스트, url등의 필드 표준 유형을 지원한다.

 

 

9.메타데이터 생성은 Custom Metadata Types에서 생성할 수 있는데

사용하고 싶은 데이터의 이름을 정해 생성한 후

해당 데이터에 들어갈 필드들을 생성해주고

해당 필드를 통해 비교할 기준(레코드)를 생성해서 관리할 수 있다.

 

예를 들어 등급제를 통한 할인율을 적용하고 싶다면

Tier 같은 metadata를 생성한 후

각각의 field에는 구매 금액, 할인율, 구매 횟수 등 원하는 기준치를 설정한다.

 

레코드 부분은 각 티어를 구분하는데 vip클럽을 기준으로 설명하자면

Red, Black, Gold, Platinum, Diamond 등의 등급이 있을 경우 아래와 같이

소비 금액, 할인율,이름에 맞게 구분하는 기준이 된다.

[(name=’Red’, minimumSpending=’0’, discountRate=’0’),

(name=’Black’, minimumSpending=’1000’, discountRate=’2’),

(name=’Gold’, minimumSpending=’5000’, discountRate=’3’),

(name=’Platinum’, minimumSpending=’20000’, discountRate=’5’),

(name=’Diamond ’, minimumSpending=’50000’, discountRate=’10’)]

 

 

10.해당 값을 통해 세부 조건을 정하고 싶은 경우

Roll-Up Summary를 사용해 소비 금액 또는 이용 횟수 등을 가져올 수 있고

Validation Rules에서 해당 값들을 바탕으로 에러를 발생시킬 수 있다.

(유효성 체크 용으로)

 

 

11.메타데이터용 필드를 생성할 경우

Any user with the Customize Application permission를 선택해야 참조가 원활하게 진행될 수 있다.

에러가 발생해 1시간 가량 권한 문제등을 찾아봤지만 가장 결정적인 문제는 여기였던 것 같다.

 

 

12.Salesforce API는 어마어마하게 방대한 환경을 가지고 있는데

Salesforce 플랫폼에서 기능을 구축할 때 설계보다는 강력한 API구축에 집중했기 때문이다.

 

Salesforce에는 대표적으로는 REST API, SOAP API, Bulk API, Pub/Sub API 라는

4개의 방대한 핵심 API가 존재한다.

 

REST API는 RESTful에 기반한 간단하고 강력한 웹 서비스로 HTTP 메서드를 통해 모든 종류의

Salesforce 기능을 사용할 수 있고 XML과 JSON을 모두 지원한다.

가벼운 요청 및 응답 프레임워크가 있고 간단하게 사용할 수 있기 때문에 모바일 및 웹앱 작성에 적합하다.

 

SOAP API는 WSDL(Web Services Description Language) 파일을 사용하여

API를 통해 데이터에 액세스하기 위한 매개변수를 엄격하게 정의하며 XML만 지원한다.

SOAP API의 대부분의 기능은 REST API로도 사용할 수 있기 때문에 요구 사항을 확인해야 하며

WSDL 파일을 API와 소비자 간의 공식적인 계약으로 사용하기 때문에 서버 간 통합을 작성하는 데 적합하다.

 

Bulk API는 대량의 데이터를 처리하는 salesforce의 특성상 개발한 특수 RESTful API로

5만개 이상의 데이터를 한번에 로드하고 쿼리할 수 있기 때문에 대규모 처리에 적합하다.

 

Pub/Sub API는 외부 시스템을 실시간 이벤트와 통합할 수 있는데

데이터가 변경될 때 트리거되는 실시간 이벤트를 구독하거나 사용자 지정 이벤트를 구독할 수 있다.

pub/sub 모델은 데이터를 얻기 위해 자주 API 요청을 할 필요가 없기 때문에 API 요청 숫자를 줄여서

변경 사항을 자주 폴링해야 하는 앱에 적합하다.

 

13.해당 기능들을 사용할 때 주의할 점은 에디션에 따라 한도가 있다는 것인데

api 사용 가능 권한이 있는 에디션을 사용하고 있어야 하며

각각의 api 한도에 대해서도 인지한 상태에서 사용해야 한다.

 

API 호출 한도 확인은 System Overview에서 할 수 있으며

30일 동안 집계된 조직의 API 호출을 보여주는 월별 API 요청 한도 등을 확인해야 한다.

 

 

14.API의 종류와 유형, 형태, 소통 방식은 아래의 표에서 볼 수 있다.

API Name Type Data Format Communication
REST API REST JSON, XML Synchronous
SOAP API SOAP (WSDL) XML Synchronous
Connect REST API REST JSON, XML Synchronous (photos are processed asynchronously)
User Interface API REST JSON Synchronous
Analytics REST API REST JSON, XML Synchronous
Bulk API REST CSV, JSON, XML Asynchronous
Metadata API SOAP (WSDL) XML Asynchronous
Pub/Sub API gRPC and protocol buffers Binary Asynchronous (stream of data)
Apex REST API REST JSON, XML, Custom Synchronous
Apex SOAP API SOAP (WSDL) XML Synchronous
Tooling API REST or SOAP (WSDL) JSON, XML, Custom Synchronous
GraphQL API GraphQL JSON Synchronous

 

 

15.REST API 부분을 진행하려고 하니 postman trail을 완료하라고 하고

해당 부분에 들어가니 salesforce postman을 연동해야 했다.

 

하단의 링크에서 Salesforce Platform APIs fork를 진행하고

https://www.postman.com/salesforce-developers/workspace/salesforce-developers

인증을 진행한 다음 endpoint에 url주소를 할당해 주면

왼쪽에 있는 컬렉션에서 원하는 요청을 편하게 작성할 수 있다.

postman 결과 이미지

 

 

16.node.js에서도 JSforce를 사용해 postman을 사용할 수 있다.

const jsforce = require("jsforce");const conn = new jsforce.Connection({
  // you can change loginUrl to connect to sandbox or prerelease env.
  // loginUrl : "https://test.salesforce.com"
});
// Log in with basic SOAP login (see documentation for other auth options)
conn.login(
  process.env.USERNAME,
  process.env.PASSWORD + process.env.SECURITY_TOKEN,
  (err, res) => {
    if (err) {
      return console.error("Failed to log in to Salesforce: ", err);
    }
    console.log("Successfully logged in!");
    // Run a SOQL query
    conn.query("SELECT Id, Name FROM Account LIMIT 5", (err, result) => {
      if (err) {
        return console.error("Failed to run SOQL query: ", err);
      }
      // Display query results
      const { records } = result;
      console.log(`Fetched ${records.length} records:`);
      records.forEach(record => {
        console.log(`- ${record.Name} (${record.Id})`);
      });
    });
  }
);

 

 

17.bulk rest api는 rest api와 유사하게 postman으로 테스트하는데

거의 동일하지만 post로 등록하는 것이 아닌

작업의 시작을 post로 알리고 id, state(open), contentUrl 등을 반환받는다.

 

주의할 점은 PATCH Close or Abort a Job 부분을 선택하라고 했는데

PATCH Abort a Job Query를 선택해서 한참 막혀있었는데

알고보니 PATCH Close or Abort a Job이 따로 존재했다.

 

데이터를 추가할 때는 PUT Upload Job Data에서 진행하는데

csv 파일을 업로드 하는 것은 binary 부분에서 진행할 수 있다.

 

전반적인 순서는 create job → put upload job data → patch close or abort a job으로 진행이 되며

추가적으로 상태 확인은 get job info, 종료 결과는 ‘get job ${state} UploadComplete’형태로 볼 수 있다.

 

과제에서 불칠절하게 CRLF로 설정하게 하고 csv는 LF로 처리되는 부분을 알려주지 않았지만

lineEnding 부분의 문제라는 것을 보고 해결할 수 있었다.

 

 

18.Pub/Sub API에서는 실시간으로 변경 사항을 캐치해 동기화를 하는 작업 등에 유용하며

변경 데이터 캡처 기능을 통해 지원되는 모든 변경 필드의 레코드 변경 사항을 추적할 수 있다.

 

Salesforce 내에서 사용자 정의 알림을 게시하고 구독할 수 있으며

사용자 및 보안 관련 활동을 모니터링 할 수도 있다.

 

 

19.이벤트 기반 시스템에는 이벤트, 이벤트 메세지, 이벤트 생성자, 이벤트 채널, 이벤트 소비자, 이벤트 버스가 존재한다.

 

각각의 이벤트가 발생할 경우 이벤트 버스에게 전송하며

그 정보가 필요한 구독자들에게 이벤트 메세지를 전송한다.

 

예를 들어 구매 요청이 앱에 들어올 경우 이벤트 트리거가 이벤트를 감지하며

이벤트 트리거를 구독하고 있는 이벤트 버스로 이벤트가 들어오고

이벤트 버스를 구독하고 있는 판매자에게 이벤트 메세지를 전달한다.

 

 

20.플랫폼 이벤트에서는 아래의 이벤트 종류만 지원한다.

  • Checkbox
  • Date
  • Date/Time
  • Number
  • Text
  • Text Area (Long)

 

21.현재 이벤트 버스에 저장되는 경우 72시간 동안 유지되지만

Spring '19 이전에 정의된 표준 볼륨 이벤트는 이벤트 버스에 24시간만 저장된다.

 

 

22.Apex, REST API 및 Enterprise API에서 프로그래밍 방식으로 이벤트를 참조할 때는

이벤트 뒤에 __e의 접미사를 붙여서 접근해야 한다.

 

예를 들어 Cloud News의 경우 Cloud_News__e로 접근해야 하고

shipping order의 경우 shipping_order__e로 접근해야 한다.

 

사용자 생성의 경우 __c, 관계의 경우 __r을 붙이는 것 처럼 직관적인 느낌이다.

 

 

23.플랫폼 이벤트는 트랙잭션이 성공적으로 커밋된 후 게시하기 때문에 안정적이지만

즉시 게시하기 옵션을 통해서 진행할 경우 롤백되지 않으며 성공 여부에 관련없이 게시할 수 있다.

 

 

24.이벤트 오브젝트를 생성 및 필드 생성을 진행한 후 이벤트 수신이 가능한데

postman 또는 soap api등을 사용해서도 이벤트를 발송할 수 있다.

 

postman으로 예를 들면 SObject Create의 기본 엔드포인트에

/services/data/v53.0/sobjects/Cloud_News__e를 추가한 다음

body에는 아래의 코드를 담아 보낼 경우 성공적으로 이벤트가 생성된다.

{
   "Location__c" : "Mountain City",
   "Urgent__c" : true,
   "News_Content__c" : "Lake Road is closed due to mudslides."
}

 

 

 

 

 

(1).백준 2711번 오타맨 고창영은 오타를 자주 내기 때문에 해당 오타를 제거해달라는 문제였다.

 

신기하게도 오타는 하나밖에 없으며 해당 순서도 알고 있기 때문에

인덱스와 일치시키기 위해 순서-1의 위치에 접근해 해당 값만 제외하고 나머지 값을 새로운 str에 할당한 다음

result에 담아 한번에 출력했다.

const input = `4
4 MISSPELL
1 PROGRAMMING
7 CONTEST
3 BALLOON`.split('\n')

const result = []

for(let i = 1 ; i < input.length ; i++){
    const [index, str] = input[i].split(' ')
    let answer = ''

    for(let j = 0 ; j < str.length ; j++){
        if(Number(index)-1 !== j){
            answer += str[j]
        }
    }
    result.push(answer)
}

console.log(result.join('\n'))

'회고' 카테고리의 다른 글

[수습일지] - 26  (0) 2023.04.21
[수습일지] - 25  (0) 2023.04.20
[수습일지] - 23  (0) 2023.04.18
[수습일지] - 22  (0) 2023.04.17
[수습일지] - 21(주말)  (0) 2023.04.16

+ Recent posts