가입 수단 5종(이메일·Google·Apple·Kakao·LINE) · 로그인 에뮬레이터 연결 · 최소 지원 Android 10

This commit is contained in:
Sn-Kinos
2026-09-01 01:03:56 +09:00
parent 1d462ebe31
commit 304ad105d6
14 changed files with 770 additions and 54 deletions
+36 -22
View File
@@ -6,30 +6,32 @@
/// 예외를 던지지 않고 [AuthNotConfigured] 로 돌려준다. 화면은 이걸 안내로 보여 준다.
library;
/// 소셜 제공자. **순서와 라벨은 시안 `시안/screens/S-A-LOGIN.html` 의 버튼 그대로다.**
/// 화면명세 `wireframe/planning/screen-spec/onboard/S-A-LOGIN.md` 도 4종으로 같다.
enum SocialProvider {
/// 가입 수단 — **정책 설계서 §P-01 확정값 5종**(답변서 v1.1 Q7).
///
/// 초안 당시 CD-18 이 미확정이라 소셜 4종(카카오·네이버·Apple·Google)만 두었는데,
/// 답변서가 **이메일 · Google · Apple · Kakao · LINE** 으로 확정했다.
/// **네이버는 확정 목록에 없고, 이메일과 LINE 이 새로 들어왔다.**
///
/// 앱 Figma 에는 WeChat · X 버튼도 그려져 있으나 답변서가 5종으로 정했으므로
/// 1차는 5종이다. 추가 시 재작업이 없도록 제공자를 인터페이스 뒤에 둔다.
enum AuthProviderKind {
email('이메일로 시작하기'),
kakao('카카오로 시작하기'),
naver('네이버로 시작하기'),
line('LINE으로 시작하기'),
apple('Apple로 시작하기'),
google('Google로 시작하기');
const SocialProvider(this.label);
const AuthProviderKind(this.label);
/// 버튼 라벨. 임의로 바꾸지 마라 — 시안 대조 대상이다.
/// 버튼 라벨. 임의로 바꾸지 마라 — 화면 대조 대상이다.
final String label;
/// 이메일은 소셜이 아니라 입력 폼이 붙는다. 화면이 이걸로 갈린다.
bool get needsForm => this == AuthProviderKind.email;
}
// 이메일 가입에 대하여 — 기능 플래그를 두지 않았다.
//
// CD-18(가입 수단) 미확정(2주차_확인요청항목 Q2)이라 이메일 경로는 구현하지 않았다.
// 플래그 상수를 하나 선언해 두는 방법도 있었지만, 그 값을 읽는 분기가 없으면
// 「false 라서 닫혀 있다」는 착각만 만든다 — 누군가 true 로 바꿔도 아무 일이 일어나지 않는다.
// 지금 이메일을 닫고 있는 것은 플래그가 아니라 AuthRepository 의 제공자 목록에
// 이메일 구현체가 없다는 사실 하나다.
//
// Q2 가 「이메일 병행」으로 오면 할 일: [SocialAuthProvider] 를 구현한 이메일 제공자를 만들고
// AuthRepository._defaultProviders() 에 추가한다. 화면 수·약관 동선도 함께 바뀐다.
/// 이전 이름. 한 번에 다 바꾸지 않아도 되게 남겨 둔다.
typedef SocialProvider = AuthProviderKind;
/// 로그인된 계정.
class AuthAccount {
@@ -42,7 +44,7 @@ class AuthAccount {
});
final String uid;
final SocialProvider? provider;
final AuthProviderKind? provider;
final String? displayName;
final String? email;
@@ -78,17 +80,15 @@ final class AuthFailed extends AuthOutcome {
final class AuthNotConfigured extends AuthOutcome {
const AuthNotConfigured(this.provider, this.missing);
final SocialProvider provider;
final AuthProviderKind provider;
/// 투입해야 하는 것들(파일명·키명). 화면과 README 에 그대로 노출한다.
final List<String> missing;
}
/// 소셜 로그인 제공자 인터페이스.
///
/// 이메일 가입이 확정되면(Q2) 같은 인터페이스로 구현체 하나가 더 붙는 자리다.
/// 로그인 제공자 인터페이스. 이메일도 같은 인터페이스를 쓴다.
abstract interface class SocialAuthProvider {
SocialProvider get provider;
AuthProviderKind get provider;
/// 실 연동 코드 경로를 가지고 있는지. 스텁이면 false.
bool get isLive;
@@ -101,6 +101,20 @@ abstract interface class SocialAuthProvider {
Future<void> signOut();
}
/// 이메일 제공자만 쓰는 확장 계약.
///
/// 소셜은 외부 창이 열리고 끝이지만 이메일은 **앱 안에서 값을 받아야 한다.**
/// [SocialAuthProvider.signIn] 하나로 묶으면 화면이 제공자 종류를 보고 분기하게
/// 되므로, 입력이 필요한 쪽만 별도 계약으로 뺀다.
abstract interface class EmailAuthProvider implements SocialAuthProvider {
Future<AuthOutcome> signInWithEmail(String email, String password);
Future<AuthOutcome> signUpWithEmail(String email, String password);
/// 비밀번호 재설정 메일 발송. Figma 「비밀번호 재설정」 화면이 이걸 부른다.
Future<AuthOutcome> sendPasswordReset(String email);
}
/// 앱 재실행·토큰 만료·다른 기기 로그아웃을 인증 상태에 반영하는 세션 경계.
///
/// 저장소는 이 인터페이스만 알며 Firebase SDK 자체는 어댑터 뒤에 둔다. 덕분에