์ฃผ์: Base URL์
http://localhost:8080/api์ ๋๋ค.Swagger UI: http://localhost:8080/api/swagger-ui/index.html
# Docker ๋ฐ ์ ํ๋ฆฌ์ผ์ด์
์์
./start-dev.sh์ด ์คํฌ๋ฆฝํธ๋ ๋ค์์ ์๋์ผ๋ก ์ํํฉ๋๋ค:
- MySQL 8.0 ์ปจํ ์ด๋ ์์ (ํฌํธ: 3306)
- phpMyAdmin ์์ (ํฌํธ: 8081)
- ์ด๊ธฐ ๋ฐ์ดํฐ ์ฝ์ (roles, admin ๊ณ์ )
- Spring Boot ์ ํ๋ฆฌ์ผ์ด์ ์์ (ํฌํธ: 8080)
์ด๊ธฐํ ์คํฌ๋ฆฝํธ(docker/mysql/init/02-insert-sample-data.sql)๊ฐ ์๋์ผ๋ก ์์ฑํ๋ ๊ณ์ :
| ์ญํ | ์์ด๋ | ๋น๋ฐ๋ฒํธ | ์ค๋ช |
|---|---|---|---|
| ๊ด๋ฆฌ์ | admin |
Admin123!@ |
์์คํ ์ ์ฒด ๊ด๋ฆฌ ๊ถํ |
๋ก๊ทธ์ธ ํ ์คํธ:
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"Admin123!@","rememberMe":false}'- ์ ํ๋ฆฌ์ผ์ด์ : http://localhost:8080/api
- Swagger UI: http://localhost:8080/api/swagger-ui/index.html
- phpMyAdmin: http://localhost:8081
- ์๋ฒ:
mysql - ์ฌ์ฉ์:
buildup - ๋น๋ฐ๋ฒํธ:
buildup123
- ์๋ฒ:
- ์ธ์ฆ/์ธ๊ฐ API (Auth)
- ๊ณ์ฝ ๊ด๋ฆฌ API (Contract)
- ํ์ผ ์ ๋ก๋ API (Upload)
- GlobalExceptionHandler ํ ์คํธ
์์ฒญ
curl -X GET 'http://localhost:8080/api/v1/auth/exists?userId=testuser001'์ฑ๊ณต ์๋ต (200)
{
"success": true,
"message": "์์ด๋ ์ค๋ณต ํ์ธ์ด ์๋ฃ๋์์ต๋๋ค",
"code": null,
"data": {
"exists": false
}
}์คํจ ์๋ต - ํ๋ผ๋ฏธํฐ ๋๋ฝ (400)
{
"success": false,
"message": "ํ์ ํ๋ผ๋ฏธํฐ๊ฐ ๋๋ฝ๋์์ต๋๋ค: userId (String)",
"code": "COMMON_403",
"data": null
}์์ฒญ ์์
curl -X POST http://localhost:8080/api/v1/auth/register/employee/step1 \
-H "Content-Type: application/json" \
-d '{
"empName": "ํ๊ธธ๋",
"userId": "testuser001",
"password": "Test123@@",
"confirmPassword": "Test123@@",
"secretKey": "SECRET-KEY-12345",
"agreeTerms": true,
"agreePrivacy": true
}'ํ๋ ์ค๋ช
empName(ํ์): ํ๊ธ, ์๋ฌธ, ๊ณต๋ฐฑ๋ง ๊ฐ๋ฅ, 1~50์userId(ํ์): ์๋ฌธ ์๋ฌธ์, ์ซ์๋ง ๊ฐ๋ฅ, 6~20์password(ํ์): ์๋ฌธ, ์ซ์, ํน์๋ฌธ์(@$!%*#?&) ํฌํจ, 8~20์confirmPassword(ํ์): password์ ์ผ์นํด์ผ ํจsecretKey(์ ํ): ํ์ฅ ์ฐ๋์ฉ, ์ต๋ 100์agreeTerms(ํ์): ์๋น์ค ์ด์ฉ์ฝ๊ด ๋์, true์ฌ์ผ ํจagreePrivacy(ํ์): ๊ฐ์ธ์ ๋ณด ์ฒ๋ฆฌ๋ฐฉ์นจ ๋์, true์ฌ์ผ ํจ
์ฑ๊ณต ์๋ต (201)
{
"success": true,
"message": "ํ์๊ฐ์
์ด ์๋ฃ๋์์ต๋๋ค",
"code": null,
"data": {
"userId": "testuser001",
"empName": "ํ๊ธธ๋",
"registrationToken": "550e8400-e29b-41d4-a716-446655440000",
"expiresAt": "2025-11-11T15:30:00"
}
}์คํจ ์๋ต - Validation ์ค๋ฅ (400)
{
"success": false,
"message": "ํ๋ ๊ฒ์ฆ์ ์คํจํ์ต๋๋ค.",
"code": "COMMON_401",
"data": {
"password": "๋น๋ฐ๋ฒํธ๋ ์๋ฌธ, ์ซ์, ํน์๋ฌธ์(@$!%*#?&)๋ฅผ ํฌํจํด์ผ ํฉ๋๋ค",
"userId": "๋ก๊ทธ์ธ ID๋ ์๋ฌธ ์๋ฌธ์์ ์ซ์๋ง ์
๋ ฅ ๊ฐ๋ฅํฉ๋๋ค"
}
}์คํจ ์๋ต - ์์ด๋ ์ค๋ณต (409)
{
"success": false,
"message": "์ด๋ฏธ ์ฌ์ฉ ์ค์ธ ์์ด๋์
๋๋ค",
"code": "AUTH_1006",
"data": null
}์์ฒญ ์์
curl -X POST http://localhost:8080/api/v1/auth/register/employee/step2 \
-H "Content-Type: application/json" \
-d '{
"registrationToken": "550e8400-e29b-41d4-a716-446655440000",
"residentNum": "990101-1234567",
"phone": "01012345678",
"email": "test@example.com",
"empAddress": "์์ธ์ ๊ฐ๋จ๊ตฌ ํ
ํค๋๋ก 123",
"emergencyPhone": "01087654321"
}'ํ๋ ์ค๋ช
registrationToken(ํ์): 1๋จ๊ณ ์๋ฃ ์ ๋ฐ๊ธ๋ฐ์ ํ ํฐresidentNum(ํ์): ์ฃผ๋ฏผ๋ฑ๋ก๋ฒํธ ํ์ (XXXXXX-XXXXXXX), AES-256-GCM ์ํธํ ์ ์ฅphone(ํ์): ํด๋ํฐ ๋ฒํธ (010XXXXXXXX, ์ซ์๋ง)email(์ ํ): ์ด๋ฉ์ผ ํ์empAddress(์ ํ): ์ฃผ์, ์ต๋ 255์emergencyPhone(์ ํ): ๋น์์ฐ๋ฝ๋ง (11์๋ฆฌ ์ซ์)
์ฑ๊ณต ์๋ต (200)
{
"success": true,
"message": "๊ทผ๋ก์ ์ ๋ณด๊ฐ ์
๋ฐ์ดํธ๋์์ต๋๋ค",
"code": null,
"data": {
"userId": "testuser001",
"empName": "ํ๊ธธ๋",
"role": "EMPLOYEE",
"profileData": {
"phone": "01012345678",
"email": "test@example.com",
"empAddress": "์์ธ์ ๊ฐ๋จ๊ตฌ ํ
ํค๋๋ก 123"
}
}
}์คํจ ์๋ต - ํ ํฐ ๋ง๋ฃ/๋ฌดํจ (401)
{
"success": false,
"message": "๋ฑ๋ก ํ ํฐ์ด ๋ง๋ฃ๋์๊ฑฐ๋ ์ ํจํ์ง ์์ต๋๋ค",
"code": "AUTH_1012",
"data": null
}์์ฒญ ์์
curl -X POST http://localhost:8080/api/v1/auth/register/manager \
-H "Content-Type: application/json" \
-d '{
"managerName": "๊น์ฒ ์",
"userId": "manager001",
"password": "Manager123!@",
"confirmPassword": "Manager123!@",
"secretKey": "MANAGER-SECRET-KEY-12345",
"phone": "010-1234-5678"
}'ํ๋ ์ค๋ช
managerName(ํ์): ํ๊ธ, ์๋ฌธ, ๊ณต๋ฐฑ๋ง ๊ฐ๋ฅ, 1~50์userId(ํ์): ์๋ฌธ ์๋ฌธ์, ์ซ์๋ง ๊ฐ๋ฅ, 6~20์password(ํ์): ์๋ฌธ, ์ซ์, ํน์๋ฌธ์(@$!%*#?&) ํฌํจ, 8~20์confirmPassword(ํ์): password์ ์ผ์นํด์ผ ํจsecretKey(ํ์): ํ์ฅ ๊ด๋ฆฌ์์ฉ ์ํฌ๋ฆฟํค, ์ต๋ 100์phone(ํ์): ์ ํ๋ฒํธ (010-XXXX-XXXX ๋๋ 01XXXXXXXXX)
์ฑ๊ณต ์๋ต (201)
{
"success": true,
"message": "ํ์ฅ ๊ด๋ฆฌ์ ํ์๊ฐ์
์ด ์๋ฃ๋์์ต๋๋ค",
"code": null,
"data": {
"userId": "manager001",
"role": "MANAGER",
"profileData": {
"managerName": "๊น์ฒ ์",
"phone": "010-1234-5678"
}
}
}์์ฒญ ์์ 1: ํ ์คํธ ๊ทผ๋ก์ ๊ณ์
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-c cookies.txt \
-d '{
"username": "testuser001",
"password": "Test123@@",
"rememberMe": false
}'์์ฒญ ์์ 2: ํ ์คํธ ๊ด๋ฆฌ์ ๊ณ์
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-c cookies.txt \
-d '{
"username": "manager001",
"password": "Manager123!@",
"rememberMe": true
}'ํ๋ ์ค๋ช
username(ํ์): ๋ก๊ทธ์ธ IDpassword(ํ์): ๋น๋ฐ๋ฒํธrememberMe(์ ํ): true(30์ผ), false(7์ผ), ๊ธฐ๋ณธ๊ฐ false
์ฑ๊ณต ์๋ต (200)
{
"success": true,
"message": "๋ก๊ทธ์ธ ์ฑ๊ณต",
"code": null,
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"tokenType": "Bearer",
"expiresIn": 3600,
"userId": "testuser001",
"role": "EMPLOYEE"
}
}์๋ต ํค๋
Set-Cookie: refreshToken=<JWT_TOKEN>; Path=/; Max-Age=604800; HttpOnly; Secure; SameSite=Strict
์คํจ ์๋ต - ์ธ์ฆ ์คํจ (401)
{
"success": false,
"message": "์์ด๋ ๋๋ ๋น๋ฐ๋ฒํธ๊ฐ ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค",
"code": "AUTH_1005",
"data": null
}์คํจ ์๋ต - Role ์์ (403)
{
"success": false,
"message": "์ฌ์ฉ์์ ์ญํ ์ด ์ค์ ๋์ง ์์์ต๋๋ค. ๊ด๋ฆฌ์์๊ฒ ๋ฌธ์ํ์ธ์.",
"code": "AUTH_1013",
"data": null
}์์ฒญ ์์
curl -X GET http://localhost:8080/api/v1/auth/me \
-H "Authorization: Bearer <ACCESS_TOKEN>"์ฑ๊ณต ์๋ต - ๊ทผ๋ก์ (200)
{
"success": true,
"message": "์ฌ์ฉ์ ์ ๋ณด ์กฐํ ์ฑ๊ณต",
"code": null,
"data": {
"userId": "testuser001",
"role": "EMPLOYEE",
"profileData": {
"empName": "ํ๊ธธ๋",
"phone": "01012345678",
"email": "test@example.com",
"empAddress": "์์ธ์ ๊ฐ๋จ๊ตฌ ํ
ํค๋๋ก 123"
}
}
}์ฑ๊ณต ์๋ต - ๊ด๋ฆฌ์ (200)
{
"success": true,
"message": "์ฌ์ฉ์ ์ ๋ณด ์กฐํ ์ฑ๊ณต",
"code": null,
"data": {
"userId": "manager001",
"role": "MANAGER",
"profileData": {
"managerName": "๊น์ฒ ์",
"phone": "010-1234-5678",
"siteId": 1
}
}
}์คํจ ์๋ต - ํ ํฐ ์์/๋ง๋ฃ (401)
{
"success": false,
"message": "์ธ์ฆ ํ ํฐ์ด ์ ํจํ์ง ์์ต๋๋ค",
"code": "AUTH_1003",
"data": null
}์์ฒญ ์์
curl -X POST http://localhost:8080/api/v1/auth/token/refresh \
-H "Content-Type: application/json" \
-b cookies.txt \
-c cookies.txt์ฑ๊ณต ์๋ต (200)
{
"success": true,
"message": "ํ ํฐ ์ฌ๋ฐ๊ธ ์ฑ๊ณต",
"code": null,
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"tokenType": "Bearer",
"expiresIn": 3600,
"userId": "testuser001",
"role": "EMPLOYEE"
}
}์คํจ ์๋ต - Refresh Token ์์ (401)
{
"success": false,
"message": "Refresh Token์ ์ฐพ์ ์ ์์ต๋๋ค",
"code": "AUTH_1008",
"data": null
}์ฃผ์: ๋ชจ๋ ๊ณ์ฝ API๋ ์ธ์ฆ์ด ํ์ํ๋ฉฐ, ์ญํ ๋ณ ์ ๊ทผ ์ ์ด๊ฐ ์ ์ฉ๋ฉ๋๋ค.
์์ฒญ ์์ 1: ๊ธฐ๋ณธ ์กฐํ
curl -X GET 'http://localhost:8080/api/v1/1/contracts' \
-H "Authorization: Bearer <ACCESS_TOKEN>"์์ฒญ ์์ 2: ํํฐ๋ง + ํ์ด์ง
curl -X GET 'http://localhost:8080/api/v1/1/contracts?employeeId=1&status=FULLY_SIGNED&page=1&size=20' \
-H "Authorization: Bearer <ACCESS_TOKEN>"์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ
siteId(Path ํ์): ํ์ฅ IDemployeeId(์ ํ): ๊ทผ๋ก์ ID ํํฐempType(์ ํ): DAILY(์ผ์ฉ์ง) ๋๋ PERMANENT(์์ฉ์ง)status(์ ํ): DRAFT(์ด์), PENDING(๋๊ธฐ์ค), FULLY_SIGNED(์๋ฃ)from(์ ํ): ๊ณ์ฝ ์์์ผ ๋ฒ์ ์์ (YYYY-MM-DD)to(์ ํ): ๊ณ์ฝ ์์์ผ ๋ฒ์ ์ข ๋ฃ (YYYY-MM-DD)page(์ ํ): ํ์ด์ง ๋ฒํธ, ๊ธฐ๋ณธ๊ฐ 1size(์ ํ): ํ์ด์ง ํฌ๊ธฐ, ๊ธฐ๋ณธ๊ฐ 20, ์ต๋ 100
์ฑ๊ณต ์๋ต (200)
{
"success": true,
"message": "๊ณ์ฝ ๋ชฉ๋ก ์กฐํ๊ฐ ์๋ฃ๋์์ต๋๋ค",
"code": null,
"data": {
"contracts": [
{
"contractId": 1,
"empType": "PERMANENT",
"status": "FULLY_SIGNED",
"employeeStartDate": "2024-01-01",
"employeeEndDate": null,
"employeeName": "ํ๊ธธ๋",
"residentNum": "990101-1******",
"corporationName": "์ฃผ์ํ์ฌ ๋น๋์
",
"createdAt": "2024-01-01T09:00:00"
}
],
"pageInfo": {
"currentPage": 1,
"pageSize": 20,
"totalElements": 1,
"totalPages": 1
}
}
}์คํจ ์๋ต - ๊ถํ ์์ (403)
{
"success": false,
"message": "์ ๊ทผ ๊ถํ์ด ์์ต๋๋ค",
"code": "AUTH_1011",
"data": null
}์์ฒญ ์์
curl -X POST http://localhost:8080/api/v1/1/contracts/regular \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"employeeId": 1,
"corporationId": 1,
"managerId": 1,
"role": "ํ์ฅ ๊ด๋ฆฌ์",
"empType": "PERMANENT",
"employeeStartDate": "2024-01-01",
"employeeEndDate": null,
"details": {
"workPlace": "์์ธ์ ๊ฐ๋จ๊ตฌ ํ
ํค๋๋ก 123",
"workType": "์ผ๋ฐ๊ฑด์คํ์ฅ๊ทผ๋ก์",
"workStartTime": "09:00:00",
"workEndTime": "18:00:00",
"breakStartTime": "12:00:00",
"breakEndTime": "13:00:00",
"workOnDays": "์~๊ธ",
"workOffDays": "ํ , ์ผ",
"workPay": 3000000.00,
"additionalHourPay": 150000.00,
"additionalNightPay": 100000.00,
"additionalHolidayPay": 200000.00,
"payDay": 25,
"payPeriod": "MONTHLY",
"payType": "TRANSFER",
"isEoiApplicable": true,
"isWciApplicable": true,
"isNpsApplicable": true,
"isNhiApplicable": true
}
}'ํ๋ ์ค๋ช (๊ธฐ๋ณธ ์ ๋ณด)
employeeId(ํ์): ๊ทผ๋ก์ IDcorporationId(ํ์): ๊ธฐ์ IDmanagerId(์ ํ): ๊ด๋ฆฌ์ IDrole(์ ํ): ๊ณ์ฝ ์ ์ญํempType(ํ์): PERMANENT๋ง ํ์ฉ (์์ฉ์ง)employeeStartDate(ํ์): ๊ทผ๋ก ์์์ผ (YYYY-MM-DD)employeeEndDate(์ ํ): ๊ทผ๋ก ์ข ๋ฃ์ผ, null์ด๋ฉด ๊ณ์ ๊ทผ๋กdetails(ํ์): ๊ณ์ฝ ์์ธ ์ ๋ณด (์๋ ์ฐธ์กฐ)
ํ๋ ์ค๋ช (details - ๊ทผ๋ฌด ์ ๋ณด)
workPlace(์ ํ): ๊ทผ๋ฌด ์ฅ์workType(์ ํ): ์ง์ขworkStartTime(์ ํ): ๊ทผ๋ฌด ์์ ์๊ฐ (HH:MM:SS)workEndTime(์ ํ): ๊ทผ๋ฌด ์ข ๋ฃ ์๊ฐbreakStartTime(์ ํ): ํด๊ฒ ์์ ์๊ฐbreakEndTime(์ ํ): ํด๊ฒ ์ข ๋ฃ ์๊ฐworkOnDays(์ ํ): ๊ทผ๋ฌด์ผworkOffDays(์ ํ): ํด์ผ
ํ๋ ์ค๋ช (details - ๊ธ์ฌ ์ ๋ณด)
workPay(ํ์): ๊ธฐ๋ณธ ์๊ธadditionalHourPay(์ ํ): ์๊ฐ์ธ ๊ทผ๋ก ์๋นadditionalNightPay(์ ํ): ์ผ๊ฐ ๊ทผ๋ก ์๋นadditionalHolidayPay(์ ํ): ํด์ผ ๊ทผ๋ก ์๋น
ํ๋ ์ค๋ช (details - ์ง๊ธ ์ ๋ณด)
payDay(ํ์): ์๊ธ ์ง๊ธ์ผ (1~31)payPeriod(ํ์): DAILY(์ผ๊ธ), WEEKLY(์ฃผ๊ธ), MONTHLY(์๊ธ)payType(ํ์): CASH(ํ๊ธ), TRANSFER(๊ณ์ข์ด์ฒด)
ํ๋ ์ค๋ช (details - 4๋๋ณดํ)
isEoiApplicable(์ ํ): ๊ณ ์ฉ๋ณดํ ์ ์ฉ ์ฌ๋ถisWciApplicable(์ ํ): ์ฐ์ฌ๋ณดํ ์ ์ฉ ์ฌ๋ถisNpsApplicable(์ ํ): ๊ตญ๋ฏผ์ฐ๊ธ ์ ์ฉ ์ฌ๋ถisNhiApplicable(์ ํ): ๊ฑด๊ฐ๋ณดํ ์ ์ฉ ์ฌ๋ถ
์ฑ๊ณต ์๋ต (201)
{
"success": true,
"message": "์์ฉ์ง ๊ณ์ฝ์ด ์์ฑ๋์์ต๋๋ค",
"code": null,
"data": {
"contractId": 1,
"status": "DRAFT",
"empType": "PERMANENT",
"createdAt": "2024-01-01T09:00:00"
}
}์คํจ ์๋ต - ๊ทผ๋ก์ ํ์ ๋ถ์ผ์น (422)
{
"success": false,
"message": "๊ทผ๋ก์์๊ฒ ์ด๋ฏธ ๋ค๋ฅธ ํ์
์ ๊ณ์ฝ์ด ์กด์ฌํฉ๋๋ค",
"code": "CONTRACT_2003",
"data": null
}์์ฒญ ์์
curl -X POST http://localhost:8080/api/v1/1/contracts/daily \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"employeeId": 2,
"corporationId": 1,
"managerId": 1,
"role": "ํ์ฅ ๊ด๋ฆฌ์",
"empType": "DAILY",
"employeeStartDate": "2024-01-01",
"employeeEndDate": "2024-01-31",
"details": {
"workPlace": "์์ธ์ ๊ฐ๋จ๊ตฌ ํ
ํค๋๋ก 123",
"workType": "์ผ๋ฐ๊ฑด์คํ์ฅ๊ทผ๋ก์",
"workStartTime": "09:00:00",
"workEndTime": "18:00:00",
"breakStartTime": "12:00:00",
"breakEndTime": "13:00:00",
"workOnDays": "์~ํ ",
"workOffDays": "์ผ",
"workPay": 150000.00,
"additionalHourPay": 0.00,
"additionalNightPay": 0.00,
"additionalHolidayPay": 0.00,
"payDay": 1,
"payPeriod": "DAILY",
"payType": "CASH",
"isEoiApplicable": false,
"isWciApplicable": true,
"isNpsApplicable": false,
"isNhiApplicable": false
}
}'ํ๋ ์ค๋ช
- ๊ธฐ๋ณธ์ ์ผ๋ก ์์ฉ์ง๊ณผ ๋์ผ
empType์ DAILY๋ง ํ์ฉ (์ผ์ฉ์ง)- ์ผ์ฉ์ง์ ์ผ๋ฐ์ ์ผ๋ก:
employeeEndDate์ง์ (๊ณ์ฝ ์ข ๋ฃ์ผ ๋ช ์)payPeriod: DAILY (์ผ๊ธ)payType: CASH ๋๋ TRANSFER- 4๋๋ณดํ: ์ฐ์ฌ๋ณดํ๋ง ์ ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์
์ฑ๊ณต ์๋ต (201)
{
"success": true,
"message": "์ผ์ฉ์ง ๊ณ์ฝ์ด ์์ฑ๋์์ต๋๋ค",
"code": null,
"data": {
"contractId": 2,
"status": "DRAFT",
"empType": "DAILY",
"createdAt": "2024-01-01T09:00:00"
}
}์์ฒญ ์์
curl -X POST http://localhost:8080/api/v1/uploads/signatures \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"resourceType": "CONTRACT",
"resourceId": "123",
"signerRole": "EMPLOYEE",
"fileExtension": "png"
}'ํ๋ ์ค๋ช
resourceType(ํ์): ๋ฆฌ์์ค ํ์ (์: CONTRACT)resourceId(ํ์): ๋ฆฌ์์ค ID (๊ณ์ฝ ID ๋ฑ)signerRole(ํ์): ์๋ช ์ ์ญํ (EMPLOYEE, MANAGER, CORPORATION)fileExtension(ํ์): ํ์ผ ํ์ฅ์ (png, jpg, jpeg, pdf)
์ฑ๊ณต ์๋ต (200)
{
"success": true,
"message": "Presigned URL์ด ๋ฐ๊ธ๋์์ต๋๋ค.",
"code": null,
"data": {
"uploadUrl": "https://build-up-contracts.s3.ap-northeast-2.amazonaws.com/uploads/contracts/123/EMPLOYEE.png?signature=xxx",
"expiresAt": "2025-11-11T15:15:00",
"s3Key": "uploads/contracts/123/EMPLOYEE.png",
"bucket": "build-up-contracts"
}
}์ฌ์ฉ ๋ฐฉ๋ฒ
- ์ API๋ก Presigned URL ๋ฐ๊ธ
- ๋ฐ๊ธ๋ฐ์
uploadUrl๋ก PUT ์์ฒญํ์ฌ ํ์ผ ์ง์ ์ ๋ก๋:curl -X PUT "<uploadUrl>" \ -H "Content-Type: image/png" \ --data-binary @signature.png
- ์ ๋ก๋ ์๋ฃ ํ ๋ณ๋์ complete API ํธ์ถ (๊ฒ์ฆ์ฉ)
์คํจ ์๋ต - Validation ์คํจ (400)
{
"success": false,
"message": "ํ๋ ๊ฒ์ฆ์ ์คํจํ์ต๋๋ค.",
"code": "COMMON_401",
"data": {
"fileExtension": "์ง์ํ์ง ์๋ ํ์ผ ํ์์
๋๋ค. (png, jpg, jpeg, pdf๋ง ๊ฐ๋ฅ)"
}
}์์ฒญ
curl -X GET http://localhost:8080/api/v1/auth/exists์๋ต (400)
{
"success": false,
"message": "ํ์ ํ๋ผ๋ฏธํฐ๊ฐ ๋๋ฝ๋์์ต๋๋ค: userId (String)",
"code": "COMMON_403",
"data": null
}์์ฒญ
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username": "test", invalid json'์๋ต (400)
{
"success": false,
"message": "์์ฒญ ๋ณธ๋ฌธ์ ์ฝ์ ์ ์์ต๋๋ค. JSON ํ์์ ํ์ธํด์ฃผ์ธ์.",
"code": "COMMON_400",
"data": null
}์์ฒญ
curl -X DELETE http://localhost:8080/api/v1/auth/login์๋ต (405)
{
"success": false,
"message": "์ง์ํ์ง ์๋ HTTP ๋ฉ์๋์
๋๋ค: DELETE (์ง์ํ๋ ๋ฉ์๋: [POST])",
"code": "COMMON_405",
"data": null
}์์ฒญ
curl -X GET http://localhost:8080/api/v1/nonexistent์๋ต (404)
{
"success": false,
"message": "์์ฒญํ ๋ฆฌ์์ค๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค",
"code": "COMMON_404",
"data": null
}์์ฒญ
curl -X POST http://localhost:8080/api/v1/auth/register/employee/step1 \
-H "Content-Type: application/json" \
-d '{
"empName": "ํ๊ธธ๋123",
"userId": "test",
"password": "weak",
"confirmPassword": "weak",
"agreeTerms": false,
"agreePrivacy": true
}'์๋ต (400)
{
"success": false,
"message": "ํ๋ ๊ฒ์ฆ์ ์คํจํ์ต๋๋ค.",
"code": "COMMON_401",
"data": {
"empName": "์ด๋ฆ์ ํ๊ธ, ์๋ฌธ, ๊ณต๋ฐฑ๋ง ์
๋ ฅ ๊ฐ๋ฅํฉ๋๋ค",
"userId": "๋ก๊ทธ์ธ ID๋ 6์ ์ด์ 20์ ์ดํ์ฌ์ผ ํฉ๋๋ค",
"password": "๋น๋ฐ๋ฒํธ๋ 8์ ์ด์ 20์ ์ดํ์ฌ์ผ ํฉ๋๋ค",
"agreeTerms": "์๋น์ค ์ด์ฉ์ฝ๊ด์ ๋์ํด์ผ ํฉ๋๋ค"
}
}์์ฒญ - ํ ํฐ ์์ด ์ธ์ฆ ํ์ ์๋ํฌ์ธํธ ํธ์ถ
curl -X GET http://localhost:8080/api/v1/auth/me์๋ต (401)
{
"success": false,
"message": "์ธ์ฆ์ด ํ์ํฉ๋๋ค",
"code": "AUTH_1001",
"data": null
}์์ฒญ - EMPLOYEE ๊ถํ์ผ๋ก MANAGER ์ ์ฉ ์๋ํฌ์ธํธ ํธ์ถ
curl -X POST http://localhost:8080/api/v1/1/contracts/regular \
-H "Authorization: Bearer <EMPLOYEE_ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{...}'์๋ต (403)
{
"success": false,
"message": "์ ๊ทผ ๊ถํ์ด ์์ต๋๋ค",
"code": "AUTH_1011",
"data": null
}# 1. ์์ด๋ ์ค๋ณต ํ์ธ
curl -X GET 'http://localhost:8080/api/v1/auth/exists?userId=testuser002'
# 2. ํ์๊ฐ์
1๋จ๊ณ
curl -X POST http://localhost:8080/api/v1/auth/register/employee/step1 \
-H "Content-Type: application/json" \
-d '{
"empName": "๊นํ
์คํธ",
"userId": "testuser002",
"password": "Test123@@",
"confirmPassword": "Test123@@",
"secretKey": "SECRET-KEY-67890",
"agreeTerms": true,
"agreePrivacy": true
}'
# 3. ํ์๊ฐ์
2๋จ๊ณ (registrationToken์ 2๋จ๊ณ ์๋ต์์ ๋ณต์ฌ)
curl -X POST http://localhost:8080/api/v1/auth/register/employee/step2 \
-H "Content-Type: application/json" \
-d '{
"registrationToken": "<๋ณต์ฌํ ํ ํฐ>",
"residentNum": "950505-2123456",
"phone": "01098765432",
"email": "test2@example.com",
"empAddress": "๊ฒฝ๊ธฐ๋ ์ฑ๋จ์ ๋ถ๋น๊ตฌ",
"emergencyPhone": "01011112222"
}'
# 4. ๋ก๊ทธ์ธ
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-c cookies.txt \
-d '{
"username": "testuser002",
"password": "Test123@@",
"rememberMe": false
}'
# 5. ๋ด ์ ๋ณด ์กฐํ (accessToken์ ๋ก๊ทธ์ธ ์๋ต์์ ๋ณต์ฌ)
curl -X GET http://localhost:8080/api/v1/auth/me \
-H "Authorization: Bearer <๋ณต์ฌํ accessToken>"
# 6. ํ ํฐ ์ฌ๋ฐ๊ธ
curl -X POST http://localhost:8080/api/v1/auth/token/refresh \
-b cookies.txt \
-c cookies.txt# 1. ํ์ฅ ๊ด๋ฆฌ์ ํ์๊ฐ์
curl -X POST http://localhost:8080/api/v1/auth/register/manager \
-H "Content-Type: application/json" \
-d '{
"managerName": "์ด๊ด๋ฆฌ",
"userId": "manager002",
"password": "Manager123!@",
"confirmPassword": "Manager123!@",
"secretKey": "MANAGER-SECRET-999",
"phone": "010-9999-8888"
}'
# 2. ๋ก๊ทธ์ธ
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-c cookies.txt \
-d '{
"username": "manager002",
"password": "Manager123!@",
"rememberMe": false
}'
# 3. ์์ฉ์ง ๊ณ์ฝ ์์ฑ (accessToken ๋ณต์ฌ, employeeId๋ ๊ธฐ์กด ๊ทผ๋ก์ ID ์ฌ์ฉ)
curl -X POST http://localhost:8080/api/v1/1/contracts/regular \
-H "Authorization: Bearer <๋ณต์ฌํ accessToken>" \
-H "Content-Type: application/json" \
-d '{
"employeeId": 1,
"corporationId": 1,
"managerId": 1,
"role": "ํ์ฅ ๊ด๋ฆฌ์",
"empType": "PERMANENT",
"employeeStartDate": "2024-02-01",
"employeeEndDate": null,
"details": {
"workPlace": "์ธ์ฒ์ ์ฐ์๊ตฌ ์ก๋๊ตญ์ ๋์",
"workType": "๊ฑด์ถ๊ณต์ฌ ํ์ฅ๊ทผ๋ก์",
"workStartTime": "08:00:00",
"workEndTime": "17:00:00",
"breakStartTime": "12:00:00",
"breakEndTime": "13:00:00",
"workOnDays": "์~๊ธ",
"workOffDays": "ํ , ์ผ, ๊ณตํด์ผ",
"workPay": 3500000.00,
"additionalHourPay": 200000.00,
"additionalNightPay": 150000.00,
"additionalHolidayPay": 250000.00,
"payDay": 25,
"payPeriod": "MONTHLY",
"payType": "TRANSFER",
"isEoiApplicable": true,
"isWciApplicable": true,
"isNpsApplicable": true,
"isNhiApplicable": true
}
}'
# 4. ๊ณ์ฝ ๋ชฉ๋ก ์กฐํ
curl -X GET 'http://localhost:8080/api/v1/1/contracts?page=1&size=20' \
-H "Authorization: Bearer <๋ณต์ฌํ accessToken>"์๋ JSON์ ๋ณต์ฌํ์ฌ Postman์์ Import โ Raw text๋ก ์ํฌํธํ ์ ์์ต๋๋ค.
{
"info": {
"name": "Build-Up Platform API",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"variable": [
{
"key": "base_url",
"value": "http://localhost:8080/api",
"type": "string"
},
{
"key": "access_token",
"value": "",
"type": "string"
}
],
"item": [
{
"name": "Auth",
"item": [
{
"name": "์์ด๋ ์ค๋ณต ํ์ธ",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{base_url}}/v1/auth/exists?userId=testuser001",
"host": ["{{base_url}}"],
"path": ["v1", "auth", "exists"],
"query": [
{
"key": "userId",
"value": "testuser001"
}
]
}
}
},
{
"name": "๊ทผ๋ก์ ํ์๊ฐ์
1๋จ๊ณ",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"empName\": \"ํ๊ธธ๋\",\n \"userId\": \"testuser001\",\n \"password\": \"Test123@@\",\n \"confirmPassword\": \"Test123@@\",\n \"secretKey\": \"SECRET-KEY-12345\",\n \"agreeTerms\": true,\n \"agreePrivacy\": true\n}"
},
"url": {
"raw": "{{base_url}}/v1/auth/register/employee/step1",
"host": ["{{base_url}}"],
"path": ["v1", "auth", "register", "employee", "step1"]
}
}
},
{
"name": "๋ก๊ทธ์ธ",
"event": [
{
"listen": "test",
"script": {
"exec": [
"const response = pm.response.json();",
"if (response.success && response.data.accessToken) {",
" pm.collectionVariables.set('access_token', response.data.accessToken);",
"}"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"username\": \"testuser001\",\n \"password\": \"Test123@@\",\n \"rememberMe\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/auth/login",
"host": ["{{base_url}}"],
"path": ["v1", "auth", "login"]
}
}
},
{
"name": "๋ด ์ ๋ณด ์กฐํ",
"request": {
"method": "GET",
"header": [
{
"key": "Authorization",
"value": "Bearer {{access_token}}"
}
],
"url": {
"raw": "{{base_url}}/v1/auth/me",
"host": ["{{base_url}}"],
"path": ["v1", "auth", "me"]
}
}
}
]
},
{
"name": "Contract",
"item": [
{
"name": "๊ณ์ฝ ๋ชฉ๋ก ์กฐํ",
"request": {
"method": "GET",
"header": [
{
"key": "Authorization",
"value": "Bearer {{access_token}}"
}
],
"url": {
"raw": "{{base_url}}/v1/1/contracts?page=1&size=20",
"host": ["{{base_url}}"],
"path": ["v1", "1", "contracts"],
"query": [
{
"key": "page",
"value": "1"
},
{
"key": "size",
"value": "20"
}
]
}
}
},
{
"name": "์์ฉ์ง ๊ณ์ฝ ์์ฑ",
"request": {
"method": "POST",
"header": [
{
"key": "Authorization",
"value": "Bearer {{access_token}}"
},
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"employeeId\": 1,\n \"corporationId\": 1,\n \"managerId\": 1,\n \"role\": \"ํ์ฅ ๊ด๋ฆฌ์\",\n \"empType\": \"PERMANENT\",\n \"employeeStartDate\": \"2024-01-01\",\n \"employeeEndDate\": null,\n \"details\": {\n \"workPlace\": \"์์ธ์ ๊ฐ๋จ๊ตฌ ํ
ํค๋๋ก 123\",\n \"workType\": \"์ผ๋ฐ๊ฑด์คํ์ฅ๊ทผ๋ก์\",\n \"workStartTime\": \"09:00:00\",\n \"workEndTime\": \"18:00:00\",\n \"breakStartTime\": \"12:00:00\",\n \"breakEndTime\": \"13:00:00\",\n \"workOnDays\": \"์~๊ธ\",\n \"workOffDays\": \"ํ , ์ผ\",\n \"workPay\": 3000000.00,\n \"additionalHourPay\": 150000.00,\n \"additionalNightPay\": 100000.00,\n \"additionalHolidayPay\": 200000.00,\n \"payDay\": 25,\n \"payPeriod\": \"MONTHLY\",\n \"payType\": \"TRANSFER\",\n \"isEoiApplicable\": true,\n \"isWciApplicable\": true,\n \"isNpsApplicable\": true,\n \"isNhiApplicable\": true\n }\n}"
},
"url": {
"raw": "{{base_url}}/v1/1/contracts/regular",
"host": ["{{base_url}}"],
"path": ["v1", "1", "contracts", "regular"]
}
}
}
]
}
]
}| ์๋ฌ ์ฝ๋ | HTTP | ์ค๋ช |
|---|---|---|
| COMMON_400 | 400 | ์๋ชป๋ ์์ฒญ (JSON ํ์ฑ ์ค๋ฅ) |
| COMMON_401 | 400 | Validation ์ค๋ฅ |
| COMMON_402 | 400 | ํ์ ๋ณํ ์ค๋ฅ |
| COMMON_403 | 400 | ํ์ ํ๋ผ๋ฏธํฐ ๋๋ฝ |
| COMMON_404 | 404 | ๋ฆฌ์์ค๋ฅผ ์ฐพ์ ์ ์์ |
| COMMON_405 | 405 | ์ง์ํ์ง ์๋ HTTP ๋ฉ์๋ |
| COMMON_500 | 500 | ์๋ฒ ๋ด๋ถ ์ค๋ฅ |
| ์๋ฌ ์ฝ๋ | HTTP | ์ค๋ช |
|---|---|---|
| AUTH_1001 | 401 | ์ธ์ฆ ์คํจ |
| AUTH_1003 | 401 | ์ ํจํ์ง ์์ ํ ํฐ |
| AUTH_1005 | 401 | ์๋ชป๋ ์์ด๋/๋น๋ฐ๋ฒํธ |
| AUTH_1006 | 409 | ์์ด๋ ์ค๋ณต |
| AUTH_1008 | 401 | Refresh Token ์์ |
| AUTH_1011 | 403 | ๊ถํ ์์ |
| AUTH_1012 | 401 | ๋ฑ๋ก ํ ํฐ ๋ง๋ฃ |
| AUTH_1013 | 403 | Role ์์ |
| ์๋ฌ ์ฝ๋ | HTTP | ์ค๋ช |
|---|---|---|
| CONTRACT_2001 | 404 | ๊ณ์ฝ์ ์ฐพ์ ์ ์์ |
| CONTRACT_2003 | 422 | ๊ทผ๋ก์ ํ์ ๋ถ์ผ์น |
- ๊ธธ์ด: 8~20์
- ํฌํจ: ์๋ฌธ, ์ซ์, ํน์๋ฌธ์(@$!%*#?&)
- ์์:
Test123@@,Manager123!@,Admin@2024
- ํ์:
XXXXXX-XXXXXXX(13์๋ฆฌ, ํ์ดํ ํฌํจ) - ์์:
990101-1234567 - ์ํธํ: AES-256-GCM์ผ๋ก ์ํธํ๋์ด DB ์ ์ฅ
- ๋ง์คํน: API ์๋ต ์ ๋ท์๋ฆฌ ๋ง์คํน (์:
990101-1******)
- ๊ทผ๋ก์:
010XXXXXXXX(ํ์ดํ ์์ด 11์๋ฆฌ ์ซ์) - ๊ด๋ฆฌ์:
010-XXXX-XXXX๋๋010XXXXXXXX(๋ ๋ค ๊ฐ๋ฅ)
- Access Token: ์๋ต Body์ ํฌํจ, ๋ง๋ฃ ์๊ฐ 3600์ด (1์๊ฐ)
- Refresh Token: HttpOnly ์ฟ ํค๋ก ์ ๋ฌ, ๋ง๋ฃ ์๊ฐ:
- rememberMe=false: 604800์ด (7์ผ)
- rememberMe=true: 2592000์ด (30์ผ)
- ํ ํฐ ์ฌ์ฉ:
Authorization: Bearer <ACCESS_TOKEN>ํค๋๋ก ์ ๋ฌ
- EMPLOYEE: ๋ด ์ ๋ณด ์กฐํ๋ง ๊ฐ๋ฅ
- MANAGER: ๊ณ์ฝ ์์ฑ/์กฐํ ๊ฐ๋ฅ
- CORPORATION: ๊ณ์ฝ ์กฐํ ๊ฐ๋ฅ
- ADMIN: ๋ชจ๋ ๊ถํ
๋ฌธ์ ๋ฒ์ : 1.0 ์ต์ข ์์ ์ผ: 2025-11-11 ์์ฑ์: Build-Up Team