Gallery
Search

[Spring][iLanD] [๋น๋] Jar ๋น๋ ์ดํ ์คํ ์ ํ์๋ฆฌํ ํธ๋ฌ๋ธ์ํ
[Spring][iLanD] [ํ๋ก์ ํธ์๋ฃ] ๊ฐ ๊ธฐ๋ฅ ๊ตฌํ ์์ฐ

[Spring][iLanD] [ํ๋ก์ ํธ์๋ฃ] ํOS ์คํํ๊ฒฝ ๊ตฌ์ถ๊ฐ์ด๋

[Spring][iLanD] [Mini Game] ๊ฐ์๋ฐ์๋ณด ๊ฒ์ ๊ธฐ๋ฅ ๋ฃ๊ธฐ

[Spring][iLanD] [Base64] Video ํ์ผ ์ถ๊ฐ, Img ํฌ์คํฐ์ ๋ถ๋ฆฌ, Video ํ์ผ ์ฒ๋ฆฌ ๋ก์ง ๋ถ๋ฆฌ, ์ธ์ฝ๋ฉ ํ ์ด๋ฏธ์ง ์ถ๋ ฅ, Video ํ๊ทธ๋ฅผ ํตํ ์์ ์ฌ์
์ค์๊ฐ ์ฑํ
๊ธฐ๋ฅ์ด ์ด๋์ ๋ ๊ตฌํ๋์์ผ๋ ๋ค๋ฌ๊ธฐ๋ฅผ ๋ค์ด๊ฐ๋ค. ย
์ํ๋๊ฑด ์ฑํ
์ ๊ตฌ๋ถ์ด ์๋๋๊ฒ๊ณผ ์๋ด์ ๊ฐ์ ๋ถ๋ถ์ด ๋ถ์กฑํ๋ค.
์นดํก๊ณผ ๋น์ทํ๊ฒ ๊ตฌํํด๋ณด๊ณ ์ถ๋ค. ๊ตฌํ๋ ๋ชจ์ต์ ์ฐ์ ๋ค์๊ณผ ๊ฐ๋ค. ๋ค๋ฅธ ๋ธ๋ผ์ฐ์ ๋ฅผ ํตํด์ ๋ก๊ทธ์ธ๋ ์ ์ ์ ๋ก๊ทธ์ธ๋์ง ์์ ์ ์ ์ ์ํฉ์ ์ฐ์ถํ๋ค.
แแ
ฐแธแแ
ฉแแ
ฆแบ แแ
ฆแแ
ตแซแแ
ฅ แแ
ฎแแ
งแซ.mp4
chatting.js
์ ๋ฐ์ ์ผ๋ก ์ฝ๋๊ฐ ๋ณต์กํด์ง๊ธดํ๋ค. ๋ก๊ทธ์ธ์ ์์ฑ๋๋ ํด๋ผ์ด์ธํธ ์ฟ ํค๋ก๋ถํฐ ์ฌ์ฉ์ ์ด๋ฆ์ ๋ฐ์์ค๋๋กํ๋ค. ๋ค๋ฅธ ๋ฐฉ๋ฒ๋ค๋ก user์ Authentication์ ๋ฐ์์ค๋ ๊ฒ์ ๊ตฌํํด๋ณด๊ณ ์ถ๋ค.
const client = new StompJs.Client({
brokerURL: 'ws://192.168.0.2:8080/websocket'
// ๋ธ๋ก์ปค์ฃผ์๋ฅผ ์๋ฒ IP๋ก ์์ ํด์ผํ๋ค.
// brokerURL: 'ws://localhost:8080/websocket'
});
client.onConnect = (frame) => {
setConnected(true);
console.log('Connected: ' + frame);
client.subscribe('/chatMessage', (chatting) => {
showChatting(JSON.parse(chatting.body).content);
});
};
client.onWebSocketError = (error) => {
console.error('Error with websocket', error);
};
client.onStompError = (frame) => {
console.error('Broker reported error: ' + frame.headers['message']);
console.error('Additional details: ' + frame.body);
};
function setConnected(connected) {
$("#chatConnect").prop("disabled", connected);
$("#chatDisconnect").prop("disabled", !connected);
$("#message").html("");
// ์ฐ๊ฒฐ ์ํ์ ๋ฐ๋ผ ๋ฉ์์ง ์ถ๊ฐ
var message = connected ? "[System] ์ฑํ
๋ฐฉ์ ์ฐ๊ฒฐ๋์์ต๋๋ค." : "[System] ์ฑํ
๋ฐฉ์์ ๋๊ฐ์ต๋๋ค.";
showChatting(message);
}
function connect() {
client.activate();
}
function disconnect() {
client.deactivate();
setConnected(false);
console.log("Disconnected");
}
// ํด๋ผ์ด์ธํธ์์ ํ ํฐ์ ์ถ์ถํ๋ ํจ์ ์ ์
function extractUsernameFromToken(token) {
try {
const base64Url = token.split('.')[1];
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
const payload = JSON.parse(jsonPayload);
return payload.sub; // ํ ํฐ์์ ์ ์ ์ด๋ฆ ์ถ์ถ
} catch (error) {
console.error('Error extracting username from token:', error);
return null;
}
}
// ํ ํฐ ๊ฐ์ ธ์ค๊ธฐ ํจ์ ์ ์
function getJwtToken() {
// ์ฌ๊ธฐ์์ ์ค์ ๋ก ํ ํฐ์ ๊ฐ์ ธ์ค๋ ๋ก์ง์ ์์ฑํด์ผ ํจ
// ์์๋ก ์ฟ ํค์์ ํ ํฐ์ ๊ฐ์ ธ์ค๋ ๋ฐฉ์ ์ฌ์ฉ
const name = "Authorization=";
const decodedCookie = decodeURIComponent(document.cookie);
const cookieArray = decodedCookie.split(';');
for (let i = 0; i < cookieArray.length; i++) {
let cookie = cookieArray[i].trim();
if (cookie.indexOf(name) === 0) {
return cookie.substring(name.length, cookie.length);
}
}
return null;
}
// ํ ํฐ์ด ์์ ๊ฒฝ์ฐ "[Unknown]" ๋ฐํํ๋ ํจ์
function getUsernameOrUnknown() {
const token = getJwtToken();
return token ? extractUsernameFromToken(token) : "Unknown";
}
// ์ฑํ
๋ฉ์์ง ์ ์ก ์ ์ ์ ์ด๋ฆ์ ํจ๊ป ์ ์ก
function sendMessage() {
const chattingMessage = $("#chattingMessage").val();
const username = getUsernameOrUnknown(); // ์์ : getUsernameOrUnknown ์ฌ์ฉ
if (username) {
const messageToSend = `[${username}] ${chattingMessage}`;
// ์ ์กํ ๋ฉ์์ง ๊ตฌ์ฑ
client.publish({
destination: "/app/chat",
body: JSON.stringify({'chattingMessage': messageToSend})
});
// ํ
์คํธ ์
๋ ฅ ๋ถ๋ถ์ผ๋ก ์ปค์ ์ด๋ ๋ฐ ๋ด์ฉ ๋น์ฐ๊ธฐ
$("#chattingMessage").val('').focus();
} else {
console.error('Username not available.');
}
}
function showChatting(message) {
// ๋ฉ์์ง๋ฅผ ์ถ๊ฐํ div ์์ ์ ํ
var conversationDiv = $("#conversation");
// ๋ฉ์์ง๋ฅผ ๋ด์ ์๋ก์ด div ์์ฑ
var messageDiv = $("<div>").addClass("chat-message").text(message);
// ํ์ฌ ์ ์ ์ธ์ง ํ์ธ
const isCurrentUser = message.includes(`[${getUsernameOrUnknown()}]`);
// ์ค๋ฅธ์ชฝ ์ ๋ ฌ์ด๋ฉด ํด๋์ค ์ถ๊ฐ
if (isCurrentUser) {
messageDiv.addClass("current-user");
}
// conversationDiv์ messageDiv ์ถ๊ฐ
conversationDiv.append(messageDiv);
// ์คํฌ๋กค์ ์ตํ๋จ์ผ๋ก ์ด๋ (์ ๋ฉ์์ง๊ฐ ๋ณด์ด๋๋ก)
conversationDiv.scrollTop(conversationDiv.prop("scrollHeight"));
}
$(function () {
$("#chatConnect").click(() => connect());
$("#chatDisconnect").click(() => disconnect());
$("#messageSend").click(() => sendMessage());
// textarea์์ ์ํฐ ํค ๊ฐ์ง
$("#chattingMessage").keydown(function (e) {
if (e.which === 13 && !e.shiftKey) {
e.preventDefault(); // ์ํฐ ํค ๊ธฐ๋ณธ ๋์ ๋ฐฉ์ง
$("#messageSend").click(); // ์ ์ก ๋ฒํผ ํด๋ฆญ
// ํ
์คํธ ์
๋ ฅ ๋ถ๋ถ์ผ๋ก ์ปค์ ์ด๋ ๋ฐ ๋ด์ฉ ๋น์ฐ๊ธฐ
$(this).val('').focus();
}
});
});
[Spring][iLanD] [Web Socket] ์ค์๊ฐ ์ฑํ
๊ธฐ๋ฅ ๋ค๋ฌ๊ธฐ
์น ์์ผ์ ํ์ฉํ ์ฑํ
๊ธฐ๋ฅ ๊ตฌํ ๊ณผ์
์น์์ผ์ ํ์ฉํ ์ฑํ
๊ธฐ๋ฅ์ ๊ตฌํํ๊ณ ์ํ๋ค.
Getting Started | Using WebSocket to build an interactive web application
์์กด์ฑ ์ถ๊ฐbuild.gradle ์ ์์กด์ฑ ์ถ๊ฐ
// websocket
implementation 'org.springframework.boot:spring-boot-starter-websocket'
Configuration ์ถ๊ฐ
@Configuration // ์คํ๋ง ํ๋ ์ ์ํฌ ์ค์ ํด๋์ค๋ก ๋ฑ๋ก
@EnableWebSocketMessageBroker // ์น์์ผ ์๋ฒ ํ์ฑํํ๋๋ฐ ์ฌ์ฉํ๋ค.
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
// => ์น์์ผ ์ค์ ์ ์ฌ์ฉ์ ์ ์ํ๋ค.
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/chatMessage");
//chatMessage ๋ก ์์ํ๋ ๋ชฉ์ ์ง ๋ฉ์์ง ๊ด๋ฆฌ
config.setApplicationDestinationPrefixes("/app");
//๋ชฉ์ ์ง๊ฐ /app ์์ ๋ฉ์์ง ๋ผ์ฐํ
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/websocket");
// URL์ ์น์์ผ ์๋ํฌ์ธํธ๋ก ๋ฑ๋กํ๋ค. ํด๋ผ์ด์ธํธ๋ ์ด URL์ ํตํด ์น์์ผ ์ฐ๊ฒฐ์ ์ด๊ธฐํ
}
}
๋ทฐ ์ปจํธ๋กค๋ฌ ์ถ๊ฐ
[Spring][iLanD] [Web Socket] ์ค์๊ฐ ์ฑํ
๊ธฐ๋ฅ ๊ตฌํ

[Spring][iLanD] [File] TroubleShooting - ํ์ผ ์ธ์ฝ๋ฉํด์ ์กฐํํ๊ธฐ

[Spring][iLanD] MVP - [AboutUs] @media ํ๊ทธ๋ฅผ ์ด์ฉํ ๋ฐ์ํ ์ค๋ฒ๋ ์ด ํ
์คํธ๋ฐ์ค

[Spring][iLanD] MVP - [File] ํ์ผ ์
๋ก๋ ํ๋ก์ ํธ ๊ฒฝ๋ก์ด๋ ๋ฐ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๊ตฌํ

[Spring][iLanD] MVP - [File] ํ์ผ ์
๋ก๋ ์
๋ฐ์ดํธ API ๊ตฌํ

[Spring][iLanD] [ํ๋ก์ ํธ์๋ฃ] ์ธ๋ถ ์ ์ ํ๊ฒฝ ๊ตฌ์ฑ ์๋ฃ ๋ชจ์ต

[Spring][iLanD] MVP - [File] ๊ณต์ง ์ฐ๊ด๊ด๊ณ ์ญ์ ์ ํ์ผ ์ญ์ ๊ตฌํ

[Spring][iLanD] MVP - [File] ํ์ผ ์
๋ก๋ API ๊ตฌํ

[Spring][iLanD] ์ธํธ๋ผ๋ท ์คํ ํ๊ฒฝ ๊ฐ๋จ ํ
์คํธ

[Spring][iLanD] MVP - [Notice] ํ์ด์ง ์ฒ๋ฆฌ ๊ตฌํ

[Spring][iLanD] MVP - [Admin] ๋ก๊ทธ์ธ ํ๋ก ํธ ์ฐ๊ฒฐ ๋ฐ ๊ด๋ฆฌ์ ํ์ด์ง ๊ตฌํ
์น ์์ผ์ ํ์ฉํ ์ค์๊ฐ ๊ทธ๋ฆผํ ๊ธฐ๋ฅ
[๋ช
์ฐ๋๋ท์ปด] ์น ์ค์๊ฐ ๊ทธ๋ฆผํ ๋ง๋ค๊ธฐ(4)
๋ชจ๋ฐ์ผ ํฐ์น ๋ฐ์์ด ์์ด์ ์ ์ธ๋จ
JS๋ก ๊ฒ์์ ๋ฃ๋๊ฒ ์ฌ์ดํธ, ๊ฒ์ ์์ฒด๋ง์ผ๋ก ํ๋์ ํ๋ก์ ํธ๊ธ์ด๋ผ ํด๋น ํ๋ก์ ํธ์์๋ ๊ตฌํ ์ด๋ ค์
์น ์์ผ์ ํ์ฉํ ์ฑํ
์๋ฒ ๊ธฐ๋ฅ
[Spring] ์น์์ผ์ผ๋ก ์ค์๊ฐ ์ฑํ
๊ตฌํ
WebSocket์ ์ด์ฉํ ์ค์๊ฐ ์ฑํ
๊ตฌํํ๊ธฐ 1: ์๋ฒ
[Spring][iLanD] ์ฌํ ๊ธฐ๋ฅ ๋ ํผ๋ฐ์ค ํ์

[Spring][iLanD] MVP - [Home] @media ํ๊ทธ๋ฅผ ์ด์ฉํ ๋ฉ์ธ ํ์ด์ง ๋ฐ์ํ ๋ฉ๋ด ๋ณ๊ฒฝ ์ ์ฉ
์ฐธ๊ณ ์๋ฃ
์คํ๋ง ๋ถํธ ํ์ผ ์ ๋ก๋ / ํ์ผ ๋ค์ด๋ก๋
โข
MultipartFileย ํด๋์ค ์ฌ์ฉ
โข
์๋์ผ๋ก MultipartConfigElement ํด๋์ค๋ฅผ ๋น์ผ๋ก ๋ฑ๋ก
โข
ํ์ผ๋ช
์ค๋ณต๋์ง ์๋๋ก UUID ์ฌ์ฉ
์คํ๋ง ๋ถํธ ํ๋ก์ ํธ์์ ํ์ผ ์ ๋ก๋ / ๋ค์ด๋ก๋ ์์
ํ์ผ ์ ๋ก๋
โข
ํ์ผ๋ช
์ค๋ณต๋์ง ์๋๋ก ํ์ผ ์ด๋ฆ ๋ณ๊ฒฝํด์ ์
๋ก๋
[Spring][iLanD] MVP - [File] ํ์ผ ์
๋ก๋ API ๋ ํผ๋ฐ์ค ํ์

[Spring][iLanD] MVP ํ๋ก ํธ์๋์ API ์ฐ๊ฒฐ 1์ฐจ ๊ธฐ๋ณธ CRUD, Ajax๋ก ๋์ ๋ค๋น๊ฒ์ด์
๊ตฌํ

[Spring][iLanD] MVP - [Video] ์์ CRUD API

[Spring][iLanD] MVP - [Info] ์ ๋ณด API

[Spring][iLanD] MVP - [Boards] ๊ฒ์ํ CRUD API

[Spring][iLanD] MVP - [Notice] ๊ณต์ง CRUD API
๊ฒ์ํ - ๊ฒ์๊ธ(4์ข
) - ํ์ผ
๋ชจ๋ ์ฝํ
์ธ ๋ ์ฌ์ค ๊ฒ์๊ธ์ด๋ผ ๋ณผ ์ ์๋ค. ๊ทธ ์ปฌ๋ผ์ ๋ด์ฉ์ด ๋ฌ๋ผ์ง๊ฑฐ๋ ์์น๋ง ๋ฌ๋ผ์ง ๋ฟ, ํ์ผ์ด ์๋๊ฒ ์๋๊ฒ ์ถํ์ ์ถ๊ฐ๊ฐ ํ์ํ ๊ฒ์ ๊ณ ๋ คํ์ฌ ํ์ผ ํ
์ด๋ธ์ ๋ณ๋๋ก ๋ถ๋ฆฌํ๊ณ ์ฐ๊ด๊ด๊ณ๋ก ์ฒ๋ฆฌํ๋ค.
Board.java
๊ฒ์ํ์ ํ์ด๋๋ ๊ฒ์ํ ์ํฐํฐ์ด๋ค. ๊ฐ ๊ฒ์๊ธ๋ค์ ์ข
๋ฅ๋ฅผ @OneToMany ์ฐ๊ด๊ด๊ณ๋ฅผ ํตํด์ ๊ฐ ๋ฆฌ์คํธ๋ค์ ๊ฐ์ ธ์ค๋๋ก ์ค์ ํ๋ค.
package com.yzpocket.iland.entity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
@Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Table(name = "boards")
public class Board extends TimeStamped{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String title;
@Column
@Enumerated(value = EnumType.STRING)
private BoardTypeEnum type;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
@OneToMany(mappedBy = "board")
List<Notice> noticeList = new ArrayList<>();
@OneToMany(mappedBy = "board")
List<Video> videoList = new ArrayList<>();
@OneToMany(mappedBy = "board")
List<Info> infoList = new ArrayList<>();
@OneToMany(mappedBy = "board")
List<Info> gameList = new ArrayList<>();
}
Notice.java
์ฒซ๋ฒ์งธ ๊ฒ์๊ธ์ ์ํฐํฐ์ธ ๊ณต์ง ๊ฒ์๊ธ์ด๋ค. ๊ฒ์ํ:๊ณต์ง๊ฒ์๊ธ ์ 1:N ์ฐ๊ด๊ด๊ณ๋ฅผ ๊ฐ์ง๊ณ ์๋ค. ์ด๊ฒ๊ณผ ๋์ผํ๊ฒ Info, Video, Game ๊ฒ์๊ธ์ด ๋์ผํ ์ปฌ๋ผ, ์ฐ๊ด๊ด๊ณ๋ฅผ ๊ฐ์ง๊ณ ์๋ค๊ณ ์๊ฐํ๋ฉด ๋๋ค. ๋ํ์ ์ผ๋ก Notice๋ถ๋ถ์ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
package com.yzpocket.iland.entity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
@Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Table(name = "notices")
public class Notice extends TimeStamped {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long noticeId;
@Column
private String noticeTitle;
@Column
private String noticeWriter;
@Column
private String noticeContents;
@Column
@Enumerated(value = EnumType.STRING)
private NoticeTypeEnum noticeType;
@ManyToOne
@JoinColumn(name = "board_id")
private Board board;
@OneToMany(mappedBy = "notice")
List<File> fileList = new ArrayList<>();
}
[Spring][iLanD] MVP - ์ฃผ์ ์ํฐํฐ ์์ฑ ๋ฐ ์ฐ๊ด๊ด๊ณ ๊ตฌ์ฑ
์ ์ฒด ๊ณผ์
1.
์์กด์ฑ ์ถ๊ฐ
2.
UserDetailsImpl ์์ฑ
3.
UserRepository ์ถ๊ฐ
4.
UserDetailsService ์์ฑ
5.
JWT์ ํธ ํด๋์ค ์ถ๊ฐ
6.
JWTํํฐ ์ถ๊ฐ
7.
์คํ๋ง ์ํ๋ฆฌํฐ ์ค์
[Spring][iLanD] MVP - [Auth] SpringSecurity JWT+์ฟ ํค ๋ฐฉ์ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ ๊ตฌํ
ํ์ ๊ฐ์
, ์์ , ํํด API ๊ตฌํ
โข
๋น๋ฐ๋ฒํธ๋ SpringSecurity์ BCryptPasswordEncoder๋ฅผ ํตํด ๊ธฐ๋ณธ ๋จ๋ฐฉํฅ ํด์ ์๊ณ ๋ฆฌ์ฆ BCrypt ๋ก ๋ณตํธํ ๋ถ๊ฐ๋ฅํ ์ํธํ ๊ธฐ๋ฅ์ ํ์ฉ
โข
๊ธฐ๋ณธ์ ์ผ๋ก ์
๋ ฅ๊ฐ์ ์ ํจ์ฑ ๊ฒ์ฌ๋ ๋ค์๊ณผ ๊ฐ์
โข
usertype์ ํ๋ก ํธ์์ ๋๋กญ๋ค์ด๋ฐ์ค๋ก value๋ฅผ 0,1,2 ๋ฅผ ์ ๋ฌํ๋๋ก ์ค๊ณํ ์์
UserSignupRequestDto.java
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
public class UserSignupRequestDto {
@Email
@NotBlank
private String useremail;
//@Pattern(regexp = "(?=.*[0-9])(?=.*[a-zA-Z]).{4,10}", message = "์์ด๋ 4~10์ ์๋ฌธ ์๋ฌธ์, ์ซ์๋ฅผ ์ฌ์ฉํ์ธ์.")
@Pattern(regexp = "^[๊ฐ-ํฃ]{2,4}$", message = "์ด๋ฆ์ ํ๊ธ๋ก 2๊ธ์์์ 4๊ธ์๊น์ง ์
๋ ฅํ์ธ์.")
private String username;
@Pattern(regexp = "^(?=.*[a-zA-Z])((?=.*\\d)|(?=.*\\W)).{8,15}+$", message = "๋น๋ฐ๋ฒํธ๋ 8~15์ ์๋ฌธ ๋ ์๋ฌธ์, ์ซ์๋ฅผ ์ฌ์ฉํ์ธ์.")
private String password1;
private String password2;
@Builder.Default
private long usertype = 0;
@Builder.Default
private String token = "";
}
UserUpdateRequestDto.java
@Data
@Builder
public class UserUpdateRequestDto {
@Pattern(regexp = "^(?=.*[a-zA-Z])((?=.*\\d)|(?=.*\\W)).{8,15}+$", message = "๋น๋ฐ๋ฒํธ๋ 8~15์ ์๋ฌธ ๋ ์๋ฌธ์, ์ซ์๋ฅผ ์ฌ์ฉํ์ธ์.")
private String password1;
private String password2;
}
[Spring][iLanD] MVP - [Users] ํ์ CUD API
โ ย ํ์ ๊ฐ์ ๋ฐ ๋ก๊ทธ์ธ ๊ตฌํ - staff only (๋นํ์์ ๋ชจ๋ ์ ์ )
โข
ํ์ ๊ฐ์
์์
โข
๋ก๊ทธ์ธ
โ ย Notice ๊ณต์ง๊ฒ์ํ
โข
CREATE - admin or staff only (์ค์๊ณต์ง์ปฌ๋ผํ์)
โข
READ
โข
UPDATE - admin or staff only
โข
DELETE - admin or staff only
[Spring][iLanD] ๊ธฐ๋ฅ ๋ถ๋ฅ

[Spring][iLanD] ๊ธฐ์ด ํ๋ก์ ํธ ๊ตฌ์กฐ ์์ฑ ๋ฐ ์์กด์ฑ ์ฃผ์
, ํ
์คํธ

[Spring][iLanD] ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค๊ณ 1์ฐจ(ERD)
ํ๋ก ํธ์๋ ์ปจ์
๋์์ธ
์ฃผ์ ์ปจํ
์ธ ๋์์ธ
[Spring][iLanD] ํ๋ก์ ํธ ๋๋ฉ ๋ฏธํ
, ํ๋ก ํธ์๋ ๋์์ธ ๊ตฌํ ์ํ, ์ฝ๋ ํ์ธ, ๊ณผ์
๋ฒ์ ํ์ธ

[Spring][iLanD] ํ๋ก์ ํธ ์งํ ๋ก๋๋งต ์์ฑ

[Spring][iLanD] Git, Github ์ ์ฅ์ ์ฐ๊ฒฐ ๊ด๋ฆฌ
ํ๋ก์ ํธ ์ถ์ง ์ด์
์ฃผ๋ณ ๋คํธ์ํฌ๋ฅผ ํตํด ์์ง๋ง ์ค์ ๊ณผ ๊ฐ์ ๊ฒฝํ ๋์์ ์ฃผ๊ฒ ๋ค๋ ์ ์๊ฐ ๋ค์ด์์ผ๋ฉฐ ๊ฐ์ฌํ ๋ง์์ ๋คํด ์ต์ ์ ๋คํด ๋ฐฐ์ด ๊ฒ๋ค์ ํ ๋๋ก ํ๋ก์ ํธ๋ฅผ ์งํํด๋ณด๊ณ ์ ํฉ๋๋ค.
๊ต์ก๊ณผ์ ์์์ ์ฌ๋ฌ ํ ํ๋ก์ ํธ์ ๋ฌ๋ฆฌ ๋ณธ์ธ ์ค์ค๋ก ์ด๋์ ๋ ๊ฐ๋ฐ ํ ์ ์์์ง, ์ด๋ ๋ถ๋ถ๋ค์ด ๋ถ์กฑํ์ง ์ค์ ์ผ๋ก ๊ฒฝํํ๊ณ ์ถ์์ผ๋ฉฐ ํ ํ๋ก์ ํธ ํน์ฑ์ ๋ถ์
๊ณผ์ ์์ ์ง์ ๋ชป ๋ค๋ฃจ์ด๋ณธ ์ฌ๋ฌ ๊ธฐ๋ฅ๋ค์ ์ค์ค๋ก ๊ตฌํํด ๋ณผ ์ ์๋ ์ข์ ๊ธฐํ๋ผ๊ณ ์๊ฐํ์ต๋๋ค.
๋ณธ์ธ์ ๊ฐ๋ฐ ๋ฒ์, ํํฉ ํ์
โข
๊ฐ๋จํ Figma๋ฅผ ํตํด ์ ์๋ ์ปจ์
๋์์ธ์ ์์ผ๋ ๋ฐฑ์๋ API ๊ตฌ์ฑ์ ์ ํ ์๋ ์ํ
โข
API ๊ฐ๋ฐ์ด ํ์ํ๋ฉฐ ์ด์ ๋ฐ๋ผ ํ๋ก ํธ์๋์ ์ฝ๋ ๋๋ ๊ตฌ์ฑ์ด ๋ณ๊ฒฝ๋ ๊ฐ๋ฅ์ฑ์ด ์์
โข
๋์์ธ๊ณผ ์ปจ์
, ์๊ตฌ ๊ธฐ๋ฅ์ ์ต๋ํ ์ ์ง
โข
๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค๊ณ ํ์
โข
Java ๊ธฐ๋ฐ์ SpringBoot ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ฐ๋ฐ์์ ๊ฒฝํ์ , ๊ธฐ๊ฐ์ , ๊ฐํธ์ฑ์ ์ ํฉ
[Spring][iLanD] ๊ฐ๋ฐ ๊ณ์ฝ ์ฒด๊ฒฐ ๋ฐ ์ถ์ง ์ด์ , ๋ฒ์


