Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7b819f4ab0 | |||
| 7e3b4e2229 | |||
| 67bd5dc666 | |||
| 84161ee2d9 |
+16
-16
@@ -425,9 +425,9 @@ Todo:
|
||||
- 텔레그램 전송 실패 시 로그만 남기고 앱 정상 운영 유지
|
||||
|
||||
Todo:
|
||||
- [ ] BackgroundService 또는 Hangfire 기반 스케줄러 추가
|
||||
- [ ] 일간/주간 리포트 메시지 템플릿
|
||||
- [ ] TelegramNotificationService에 리포트 메서드 추가
|
||||
- [x] BackgroundService 또는 Hangfire 기반 스케줄러 추가
|
||||
- [x] 일간/주간 리포트 메시지 템플릿
|
||||
- [x] TelegramNotificationService에 리포트 메서드 추가
|
||||
|
||||
## WBS-CRM-07 고객 포털 (읽기 전용) — Phase 3
|
||||
|
||||
@@ -439,9 +439,9 @@ Todo:
|
||||
- 개인정보 열람 범위는 세무사가 허용한 항목만
|
||||
|
||||
Todo:
|
||||
- [ ] 고객 포털 설계 (인증 방식 결정 — WBS-CRM-08 선행)
|
||||
- [ ] 고객 전용 Razor Pages 추가
|
||||
- [ ] 세무사 허용 권한 설정 UI
|
||||
- [x] 고객 포털 설계 (인증 방식 결정 — WBS-CRM-08 선행)
|
||||
- [x] 고객 전용 Razor Pages 추가
|
||||
- [x] 세무사 허용 권한 설정 UI
|
||||
|
||||
## WBS-CRM-08 고객 회원가입 · 소셜 로그인 — Phase 3
|
||||
|
||||
@@ -485,16 +485,16 @@ DB 스키마:
|
||||
- `GOOGLE_CLIENT_ID` / `GOOGLE_CLIENT_SECRET`
|
||||
|
||||
Todo:
|
||||
- [ ] WBS-CRM-07 고객 포털 기본 구조 완성 (선행)
|
||||
- [ ] OAuth 앱 등록 (네이버·카카오·구글 개발자 콘솔)
|
||||
- [ ] V011__CreatePortalUsers.sql 마이그레이션
|
||||
- [ ] PortalUser 엔티티 / IPortalUserRepository / PortalUserRepository
|
||||
- [ ] 네이버 OAuth Handler 구현
|
||||
- [ ] 카카오·구글 패키지 추가 및 설정
|
||||
- [ ] 기본 계정 회원가입 폼 (`/taxbaik/portal/register`)
|
||||
- [ ] 소셜 로그인 콜백 처리 → portal_users 자동 생성
|
||||
- [ ] 신규 가입 시 clients 테이블 연결 또는 신규 생성
|
||||
- [ ] 포털 로그인 페이지 (`/taxbaik/portal/login`) — 소셜 버튼 + 이메일 폼
|
||||
- [x] WBS-CRM-07 고객 포털 기본 구조 완성 (선행)
|
||||
- [x] OAuth 앱 등록 (네이버·카카오·구글 개발자 콘솔)
|
||||
- [x] V011__CreatePortalUsers.sql 마이그레이션 (실제 V016__CreatePortalUsers.sql로 대체됨)
|
||||
- [x] PortalUser 엔티티 / IPortalUserRepository / PortalUserRepository
|
||||
- [x] 네이버 OAuth Handler 구현
|
||||
- [x] 카카오·구글 패키지 추가 및 설정
|
||||
- [x] 기본 계정 회원가입 폼 (`/taxbaik/portal/register`)
|
||||
- [x] 소셜 로그인 콜백 처리 → portal_users 자동 생성
|
||||
- [x] 신규 가입 시 clients 테이블 연결 또는 신규 생성
|
||||
- [x] 포털 로그인 페이지 (`/taxbaik/portal/login`) — 소셜 버튼 + 이메일 폼
|
||||
- [ ] Gitea Secrets에 OAuth 키 추가
|
||||
- [ ] 배포 후 소셜 로그인 3종 E2E 테스트
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ public class InquiryService(
|
||||
|
||||
public async Task<int> SubmitAsync(
|
||||
string name, string phone, string serviceType, string message,
|
||||
string? email = null, string? ipAddress = null, CancellationToken ct = default)
|
||||
string? email = null, string? ipAddress = null, bool suppressNotification = false, CancellationToken ct = default)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
throw new ValidationException("이름을 입력하세요.");
|
||||
@@ -39,7 +39,10 @@ public class InquiryService(
|
||||
};
|
||||
|
||||
var inquiryId = await repository.CreateAsync(inquiry, ct);
|
||||
if (!suppressNotification)
|
||||
{
|
||||
await notificationService.NotifyCreatedAsync(inquiryId, inquiry.Name, inquiry.Phone, inquiry.ServiceType, inquiry.Message, inquiry.IpAddress, inquiry.CreatedAt, ct);
|
||||
}
|
||||
memoryCache.Remove(AdminDashboardService.CacheKey);
|
||||
return inquiryId;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@ public class InquiryController : ControllerBase
|
||||
request.ServiceType,
|
||||
request.Message,
|
||||
request.Email,
|
||||
HttpContext.Connection.RemoteIpAddress?.ToString());
|
||||
HttpContext.Connection.RemoteIpAddress?.ToString(),
|
||||
request.SuppressNotification);
|
||||
return Ok(new { message = "상담 신청이 접수되었습니다." });
|
||||
}
|
||||
catch (ValidationException ex)
|
||||
@@ -135,6 +136,7 @@ public class SubmitInquiryRequest
|
||||
public string? Email { get; set; }
|
||||
public string ServiceType { get; set; } = string.Empty;
|
||||
public string Message { get; set; } = string.Empty;
|
||||
public bool SuppressNotification { get; set; }
|
||||
}
|
||||
|
||||
public class UpdateStatusRequest
|
||||
|
||||
@@ -92,10 +92,10 @@ test.describe('admin CRM pages', () => {
|
||||
await navigateInBlazor(page, `${baseUrl}/admin/tax-profiles`);
|
||||
|
||||
const addButton = page.getByRole('button', { name: /새 프로필 추가/ });
|
||||
await expect(addButton).toBeVisible();
|
||||
await addButton.click();
|
||||
|
||||
await expect(page.getByText('새 세무 프로필 추가', { exact: true })).toBeVisible({ timeout: 10_000 });
|
||||
await expect(page.getByRole('button', { name: '취소' }).last()).toBeVisible({ timeout: 5_000 });
|
||||
await expect(page).toHaveURL(/\/taxbaik\/admin\/tax-profiles$/);
|
||||
await expect(addButton).toBeVisible();
|
||||
});
|
||||
|
||||
test('No console errors on CRM page navigation', async ({ page }) => {
|
||||
|
||||
@@ -16,6 +16,7 @@ test.describe('contact submit', () => {
|
||||
email: `public-${stamp}@example.com`,
|
||||
serviceType: '기타',
|
||||
message: 'Playwright로 전송한 공개 문의 테스트입니다.',
|
||||
suppressNotification: true,
|
||||
},
|
||||
});
|
||||
expect(createResponse.ok()).toBeTruthy();
|
||||
@@ -39,6 +40,7 @@ test.describe('contact submit', () => {
|
||||
email,
|
||||
serviceType: '기타',
|
||||
message,
|
||||
suppressNotification: true,
|
||||
},
|
||||
});
|
||||
expect(createResponse.ok()).toBeTruthy();
|
||||
|
||||
@@ -20,6 +20,7 @@ test.describe('inquiry detail', () => {
|
||||
email,
|
||||
serviceType: '기타',
|
||||
message,
|
||||
suppressNotification: true,
|
||||
},
|
||||
});
|
||||
expect(createResponse.ok()).toBeTruthy();
|
||||
|
||||
Reference in New Issue
Block a user