콘텐츠로 이동

Mail 첫 계약 읽기

학습 목표: 알림 요청과 실제 전달 구분하기

섹션 제목: “학습 목표: 알림 요청과 실제 전달 구분하기”

첫 mail 계약은 한 수신자에게 plain-text 메시지를 처리하는 타입을 제공합니다. Mail.send는 메시지와 논리 이벤트의 idempotency key를 받습니다. 같은 key와 같은 envelope는 같은 receipt를 돌려주며, 같은 key로 envelope를 바꾸면 IDEMPOTENCY_CONFLICT입니다. 현재 preview 상태는 해당 격리 앱 프로세스의 메모리에 한정되며 durable outbox나 자동 재시도가 아닙니다.

SIMULATED_ACCEPTED는 시뮬레이션 접수입니다. 실제 SMTP 발송·배달을 뜻하지 않습니다. production은 Java SPI 인터페이스이며 provider adapter는 포함·qualified되지 않았습니다. ACCEPTED도 배달 완료가 아니며, UNKNOWN이면 결과를 확인하지 못한 상태를 성공으로 바꾸지 않습니다. 새 상태 이름은 아래 actual metadata에서 확인하세요.

현재 metadata의 대상은 springBoot입니다. 라이브러리의 native 선언이 기존 콘솔 native runner에서도 동작한다는 의미는 아닙니다. 다른 언어·플랫폼이나 storage·파일 전송·billing·preview identity의 API를 이 mail 계약에서 추정하지 않습니다.

production profile을 고르는 것만으로 실메일 연결이 준비되지 않습니다. 정확히 한 adapter와 정의 hash/profile의 일치가 필요하며, adapter가 없을 때 preview provider로 자동 대체하지 않는 계약입니다. 실제 production adapter·설정·메일 발송 절차는 아직 제공하지 않습니다.

Unibase의 SDK와 생성물은 특정 host에 종속되지 않는 것이 설계 방향입니다. 제품 미리보기의 실행 환경과 provider는 SaaS가 맡고 Market은 진입과 상품 검증 정보를 제공합니다. 이 Mail 계약이 해당 세션 환경에 연결됐다는 의미는 아닙니다. 미리보기의 역할과 연결 상태를 함께 읽으세요.

공통 계약 UB-SVC-007 · schema 1 · definition 1.0.0. 아래 타입·제약·예제는 실제 compiler의 serviceLibraries 반환 snapshot에서 읽습니다.

연결된 생산자 요구사항: UB-SVC-001, UB-SVC-002, UB-SVC-007, UB-SVC-008. 제품 모델의 Revision과 Market release 권한을 대신하는 식별자가 아닙니다.

이 정의의 hash 확인
dc0037348372262549075d959428ada46384dd4144551f11f07675d050072c6a

패키지는 unibase.mail입니다. 표의 타입 이름은 compiler가 파싱해 반환한 이름이며 원본 .uni 선언을 아래에서 함께 읽을 수 있습니다.

Mail

static MailResult send(MailMessage message, string idempotencyKey)

MailMessage

필드반환된 타입
fromstring
tostring
subjectstring
textstring
MailMessage(string from, string to, string subject, string text)

MailResult

필드반환된 타입
messageIdstring
statestring
errorCodestring
retryableboolean
compiler가 실제로 읽은 SDK 원본
package unibase.mail;

public native class Mail {
    private native Mail();
    public static native MailResult send(MailMessage message, string idempotencyKey);
}
a4839769ecb34d07694ad402c714c452ac61e6fad90bdd339ccd9a80c6377335
package unibase.mail;

public native class MailMessage {
    public string from;
    public string to;
    public string subject;
    public string text;
    public native MailMessage(string from, string to, string subject, string text);
}
9ee11642dff1f170bf94059cb7c6c378dde40a33a8e12802a47533e941254863
package unibase.mail;

public native class MailResult {
    private native MailResult();
    public string messageId;
    public string state;
    public string errorCode;
    public bool retryable;
}
3ab22c07e5d0d29dfdc7920f4d33bbbea6f6ce81785749e13785a26bd91bd1f7

목록에 선언된 대상은 springBoot입니다. 이 목록은 생성·빌드·실행·Market 연결의 QA 통과를 대신하지 않습니다.

modeprovider계약의 productionQualified
previewin-memory-v1false
productionjava-spi-v1false

생성 입력의 필드는 producer schema대로 정확히 다음 5개입니다. scopeId 값은 원본 생성 fixture의 합성 값이며 Market 로그인·소유권·방문 권한의 증거가 아닙니다.

{
  "definitionVersion": "1.0.0",
  "mailProvider": "in-memory-v1",
  "mode": "preview",
  "schemaVersion": 1,
  "scopeId": "synthetic-app-1"
}
메타데이터 항목정의된 값
주소 최대 UTF-8 bytes addressBytesMax254
자동 재시도 automaticRetryfalse
본문 최대 UTF-8 bytes bodyBytesMax4096
내용 형식 contentplain-text
동일 이벤트 처리 idempotencysame-key-same-envelope-same-receipt; changed-envelope-conflict; retained-until-process-exit
이벤트 key 형식 keyPattern[A-Za-z0-9_.:-]{1,128}
결과 messageId 형식 messageIdPattern[A-Za-z0-9_.:-]{1,128}
preview bytes 한도 previewBytesMax1048576
preview receipt 한도 previewReceiptsMax256
production 예외의 상태 productionExceptionStateUNKNOWN
수신자 수 recipients1
제목 최대 UTF-8 bytes subjectBytesMax512

상태 이름과 오류 이름도 같은 metadata에서 읽습니다. 상태 문자열이 실제 배달을 증명하지는 않습니다.

  • SIMULATED_ACCEPTED
  • ACCEPTED
  • UNKNOWN
  • REJECTED
  • INVALID_ENVELOPE
  • INVALID_IDEMPOTENCY_KEY
  • IDEMPOTENCY_CONFLICT
  • QUOTA_EXCEEDED
  • PROVIDER_FAILURE
  • PROVIDER_UNCONFIGURED
  • PROVIDER_VERSION_MISMATCH
  • UNSUPPORTED_SERVICE_PROFILE
  • UNSUPPORTED_SERVICE_TARGET

아래는 등록된 콘솔 runner 예제가 아닌 producer의 Spring Boot 생성 요청에 담긴 원본입니다. 실행 버튼을 제공하지 않으며 이 문서의 소비 검사로 앱 실행을 확인했다고 표시하지 않습니다.

package demo; import unibase.mail.*; public class Reply { public string messageId; public string state; public string errorCode; public bool retryable; public Reply(MailResult result) { this.messageId = result.messageId; this.state = result.state; this.errorCode = result.errorCode; this.retryable = result.retryable; } }
package demo; import unibase.mail.*; @Controller public class Mailer implements MailApi { public Mailer() {} @Handler public Reply send(MailRequest input) { return Reply(Mail.send(MailMessage(input.from, input.to, input.subject, input.text), input.key)); } }
package demo; @Api(path="/mail") public interface MailApi { @Post(path="") @Public Reply send(@Body(required=true, contentType="application/json") MailRequest input); }
package demo; @Schema public class MailRequest { @Field(required=true) public string from; @Field(required=true) public string to; @Field(required=true) public string subject; @Field(required=true) public string text; @Field(required=true) public string key; public MailRequest() {} }
  • object-storage — NOT_IMPLEMENTED
  • upload-download — NOT_IMPLEMENTED
  • billing — NOT_IMPLEMENTED
  • preview-identity — NOT_IMPLEMENTED

실행 가능한 예제로 넘어가는 조건

섹션 제목: “실행 가능한 예제로 넘어가는 조건”

이 생성 fixture는 같은 업무 소스에서 명시적인 profile로 변환하는 예제입니다. Market 전체 export bundle·모델 revision·로그인 권한의 증거가 아닙니다. scopeId는 신뢰된 export/runtime binding으로 공급해야 하며 사용자가 넣은 소유자 ID로 권한을 대체하지 않습니다.

등록 ID/hash·허용 환경·실제 생성/빌드/응답·UI가 확인되어야 실행 확인으로 안내합니다. 문서의 기존 runner에 이 요청이나 임의 코드를 보내지 않습니다. 안전한 예제와 확인 범위에서 기존 결과 표시 수정과 신규 예제의 수용 기준을 읽으세요.

다음은 타입·provider·오류 확인과 AI의 실제 조회 계약입니다.