{
- "email" : "gavin.lakin@hotmail.com",
- "password" : "BNc@^R!#tM&Prm0WcOIf5Jm1w",
- "nickname" : "esteban.haag"
+ "email" : "shaniqua.effertz@yahoo.com",
+ "password" : "R87zL7mO&",
+ "nickname" : "nolan.wisozk"
}
diff --git a/mysql/schema.sql b/mysql/schema.sql index bb422a2e..56acb0f8 100644 --- a/mysql/schema.sql +++ b/mysql/schema.sql @@ -57,3 +57,12 @@ CREATE TABLE likes FOREIGN KEY (user_id) REFERENCES users (id), FOREIGN KEY (post_id) REFERENCES posts (id) ON DELETE CASCADE ); + + +CREATE TABLE images +( + id BIGINT AUTO_INCREMENT, + image_url varchar(500) NOT NULL, + filename varchar(255) NOT NULL, + CONSTRAINT images_pk PRIMARY KEY (id) +); diff --git a/src/docs/asciidoc/index.html b/src/docs/asciidoc/index.html index 88a73c93..4f465e00 100644 --- a/src/docs/asciidoc/index.html +++ b/src/docs/asciidoc/index.html @@ -573,9 +573,9 @@
{
- "email" : "gavin.lakin@hotmail.com",
- "password" : "BNc@^R!#tM&Prm0WcOIf5Jm1w",
- "nickname" : "esteban.haag"
+ "email" : "shaniqua.effertz@yahoo.com",
+ "password" : "R87zL7mO&",
+ "nickname" : "nolan.wisozk"
}
POST /api/v1/auth/signup HTTP/1.1
Content-Type: application/json;charset=UTF-8
-Content-Length: 116
+Content-Length: 103
Host: docs.api.com
{
- "email" : "gavin.lakin@hotmail.com",
- "password" : "BNc@^R!#tM&Prm0WcOIf5Jm1w",
- "nickname" : "esteban.haag"
+ "email" : "shaniqua.effertz@yahoo.com",
+ "password" : "R87zL7mO&",
+ "nickname" : "nolan.wisozk"
}
{
- "email" : "williams.flatley@yahoo.com",
- "password" : "Xz#0^3%v8$yk0o%o"
+ "email" : "otto.jacobson@gmail.com",
+ "password" : "D&2t0el8"
}
POST /api/v1/auth/login HTTP/1.1
Content-Type: application/json;charset=UTF-8
-Content-Length: 79
+Content-Length: 68
Host: docs.api.com
{
- "email" : "williams.flatley@yahoo.com",
- "password" : "Xz#0^3%v8$yk0o%o"
+ "email" : "otto.jacobson@gmail.com",
+ "password" : "D&2t0el8"
}
{
- "token" : "a5fbfa1c2fd6a064babe4b7234f141fe57733ee9c53839bb31a0284a7b0a3a49b2894252b81e86078ecc0d9a7e24dc81372376b006d457ede46a8d9d1ea0ff93"
+ "token" : "f8cc772b2b817f5e4ec4b03aaaf6605bcdc99d9d86d494cbbe5c4a18e037c512855b5547445262680dd6173685c2e1eb5daf700e4f0563afb98b32088c980909"
}
PATCH /api/v1/auth/certificate?email=magnolia.becker@yahoo.com HTTP/1.1
+PATCH /api/v1/auth/certificate?email=kendall.rowe@gmail.com HTTP/1.1
Content-Type: application/json;charset=UTF-8
Host: docs.api.com
PATCH /api/v1/auth/certify?email=emery.kutch@example.com&code=Q8K940 HTTP/1.1
+PATCH /api/v1/auth/certify?email=catalina.bartell@example.com&code=3ZGzHj HTTP/1.1
Content-Type: application/json;charset=UTF-8
Host: docs.api.com
POST /api/v1/avatar-items HTTP/1.1
Content-Type: multipart/form-data;charset=UTF-8; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
-Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJvb3R3IiwiaWF0IjoxNzA1NTcwOTgyLCJleHAiOjE3MDU1NzQ1ODIsInVzZXJfaWQiOjUyODI5OTAzMH0.yILk1vXe2vX81teF_UVtLqCh-tqyCgnOYlQLUU0alnzVpxGY-3gd6oUbmHmFeMowDsoCJzGEH0G2nwHW6hCEwQ
+Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJvb3R3IiwiaWF0IjoxNzA1Njc0MzU5LCJleHAiOjE3MDU2Nzc5NTksInVzZXJfaWQiOjEyNzI2MzM3Nn0.HThvmRtfXf_PtITq8WfhX7M-99lpYq6F6MrOgHbaYXgEuucngDM-b7Q9kD-sVboph0dyEp9bOUaQJNOL6_iBeg
Accept: application/json
Host: docs.api.com
@@ -1016,10 +1016,10 @@ Response
{
- "avatarItemId" : 528299030,
+ "avatarItemId" : 127263376,
"type" : "HAIR",
"sex" : "MALE",
- "url" : "https://www.alva-reinger.org:4583/nam/harumofficiis?consectetur=esse&sequi=dolorem"
+ "url" : "https://www.zena-gleason.io:1518/in?fugit=aperiam&quis=eos"
}
@@ -1068,13 +1068,13 @@ Respons
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
-Content-Length: 165
+Content-Length: 141
{
- "avatarItemId" : 528299030,
+ "avatarItemId" : 127263376,
"type" : "HAIR",
"sex" : "MALE",
- "url" : "https://www.alva-reinger.org:4583/nam/harumofficiis?consectetur=esse&sequi=dolorem"
+ "url" : "https://www.zena-gleason.io:1518/in?fugit=aperiam&quis=eos"
}
POST /api/v1/posts HTTP/1.1
Content-Type: multipart/form-data;charset=UTF-8; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
-Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJvb3R3IiwiaWF0IjoxNzA1NTcwOTg0LCJleHAiOjE3MDU1NzQ1ODQsInVzZXJfaWQiOjF9.mTcgBjKPrrKkjVtfmEk0MJyDI-8PQyKuXrzwr2w1_I8mwQq5lT6PkW9eMPNfCee2vdtxCj6HF_U2rN_yqcbgRA
+Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJvb3R3IiwiaWF0IjoxNzA1Njc0MzY1LCJleHAiOjE3MDU2Nzc5NjUsInVzZXJfaWQiOjF9.7YEbtfN90q-vWJ47IdoUy79KtHJdjSEjVn16sm4glP5UUzuJG705VSJR740ZlBdwKCn5AUDGnOPRpxwSeUC6aA
Accept: application/json
Host: docs.api.com
@@ -1310,7 +1310,7 @@ Request e
Content-Disposition: form-data; name=request; filename=request.json
Content-Type: application/json
-{"title":"Arms and the Man","content":"Tin","coordinate":{"nx":50,"ny":127}}
+{"title":"The Grapes of Wrath","content":"Bromine","coordinate":{"nx":50,"ny":127}}
--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
Content-Disposition: form-data; name=postImg; filename=image.jpeg
Content-Type: image/jpeg
@@ -1327,11 +1327,11 @@ Response
{
"postId" : 1,
- "title" : "Arms and the Man",
- "content" : "Tin",
- "image" : "https://www.arnulfo-runolfsdottir.info/?architecto=ut&impedit=aperiam",
- "createdAt" : "2024-01-18T18:43:04.877194",
- "updatedAt" : "2024-01-18T18:43:04.877208",
+ "title" : "The Grapes of Wrath",
+ "content" : "Bromine",
+ "image" : "https://www.mac-kertzmann.info:56449/voluptas/optio#ipsam",
+ "createdAt" : "2024-01-19T23:26:05.615107",
+ "updatedAt" : "2024-01-19T23:26:05.615121",
"temperatureArrange" : {
"min" : 0.0,
"max" : 15.0
@@ -1405,15 +1405,15 @@ Respons
Vary: Access-Control-Request-Headers
Location: /api/v1/posts/1
Content-Type: application/json
-Content-Length: 314
+Content-Length: 309
{
"postId" : 1,
- "title" : "Arms and the Man",
- "content" : "Tin",
- "image" : "https://www.arnulfo-runolfsdottir.info/?architecto=ut&impedit=aperiam",
- "createdAt" : "2024-01-18T18:43:04.877194",
- "updatedAt" : "2024-01-18T18:43:04.877208",
+ "title" : "The Grapes of Wrath",
+ "content" : "Bromine",
+ "image" : "https://www.mac-kertzmann.info:56449/voluptas/optio#ipsam",
+ "createdAt" : "2024-01-19T23:26:05.615107",
+ "updatedAt" : "2024-01-19T23:26:05.615121",
"temperatureArrange" : {
"min" : 0.0,
"max" : 15.0
@@ -1489,9 +1489,9 @@ Request H
Request example
-GET /api/v1/posts/1803095596 HTTP/1.1
+GET /api/v1/posts/1452329854 HTTP/1.1
Content-Type: application/json;charset=UTF-8
-Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJvb3R3IiwiaWF0IjoxNzA1NTcwOTg0LCJleHAiOjE3MDU1NzQ1ODQsInVzZXJfaWQiOjF9.mTcgBjKPrrKkjVtfmEk0MJyDI-8PQyKuXrzwr2w1_I8mwQq5lT6PkW9eMPNfCee2vdtxCj6HF_U2rN_yqcbgRA
+Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJvb3R3IiwiaWF0IjoxNzA1Njc0MzY1LCJleHAiOjE3MDU2Nzc5NjUsInVzZXJfaWQiOjF9.7YEbtfN90q-vWJ47IdoUy79KtHJdjSEjVn16sm4glP5UUzuJG705VSJR740ZlBdwKCn5AUDGnOPRpxwSeUC6aA
Accept: application/json
Host: docs.api.com
@@ -1503,22 +1503,22 @@ Response
{
- "postId" : 1803095596,
+ "postId" : 1452329854,
"writer" : {
- "userId" : 412308604,
- "nickname" : "jay.grimes",
- "image" : "http://www.wyatt-terry.biz/?et=incidunt&possimus=saepe#maxime"
+ "userId" : 301376391,
+ "nickname" : "forrest.windler",
+ "image" : "http://www.kathy-little.io:64848/est/velitsunt"
},
- "title" : "The Lathe of Heaven",
- "content" : "Californium",
- "image" : "https://www.breanne-waelchi.org:43673/ullam/sequiodio#earum",
- "createdAt" : "2024-01-18T18:43:04.832065",
- "updatedAt" : "2024-01-18T18:43:04.832079",
+ "title" : "Arms and the Man",
+ "content" : "Gallium",
+ "image" : "http://www.lesa-becker.info/et?ea=quis&laudantium=voluptas#suscipit",
+ "createdAt" : "2024-01-19T23:26:05.484459",
+ "updatedAt" : "2024-01-19T23:26:05.484469",
"temperatureArrange" : {
"min" : 0.0,
"max" : 15.0
},
- "likeCnt" : 33,
+ "likeCnt" : 66,
"isLike" : 0
}
@@ -1613,25 +1613,25 @@ Respons
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
-Content-Length: 513
+Content-Length: 504
{
- "postId" : 1803095596,
+ "postId" : 1452329854,
"writer" : {
- "userId" : 412308604,
- "nickname" : "jay.grimes",
- "image" : "http://www.wyatt-terry.biz/?et=incidunt&possimus=saepe#maxime"
+ "userId" : 301376391,
+ "nickname" : "forrest.windler",
+ "image" : "http://www.kathy-little.io:64848/est/velitsunt"
},
- "title" : "The Lathe of Heaven",
- "content" : "Californium",
- "image" : "https://www.breanne-waelchi.org:43673/ullam/sequiodio#earum",
- "createdAt" : "2024-01-18T18:43:04.832065",
- "updatedAt" : "2024-01-18T18:43:04.832079",
+ "title" : "Arms and the Man",
+ "content" : "Gallium",
+ "image" : "http://www.lesa-becker.info/et?ea=quis&laudantium=voluptas#suscipit",
+ "createdAt" : "2024-01-19T23:26:05.484459",
+ "updatedAt" : "2024-01-19T23:26:05.484469",
"temperatureArrange" : {
"min" : 0.0,
"max" : 15.0
},
- "likeCnt" : 33,
+ "likeCnt" : 66,
"isLike" : 0
}
@@ -1687,7 +1687,7 @@ Request e
GET /api/v1/posts HTTP/1.1
Content-Type: application/json;charset=UTF-8
-Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJvb3R3IiwiaWF0IjoxNzA1NTcwOTg0LCJleHAiOjE3MDU1NzQ1ODQsInVzZXJfaWQiOjF9.mTcgBjKPrrKkjVtfmEk0MJyDI-8PQyKuXrzwr2w1_I8mwQq5lT6PkW9eMPNfCee2vdtxCj6HF_U2rN_yqcbgRA
+Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJvb3R3IiwiaWF0IjoxNzA1Njc0MzY1LCJleHAiOjE3MDU2Nzc5NjUsInVzZXJfaWQiOjF9.7YEbtfN90q-vWJ47IdoUy79KtHJdjSEjVn16sm4glP5UUzuJG705VSJR740ZlBdwKCn5AUDGnOPRpxwSeUC6aA
Accept: application/json
Host: docs.api.com
@@ -1699,58 +1699,58 @@ Response
[ {
- "postId" : 1908042653,
+ "postId" : 391756997,
"writer" : {
- "userId" : 934467639,
- "nickname" : "alfredo.schmidt",
- "image" : "http://www.king-huels.com:45991/nemo/et?quas=vero&debitis=consequatur#ut"
+ "userId" : 563328115,
+ "nickname" : "kraig.waters",
+ "image" : "http://www.ethyl-rau.net/fuga#et"
},
- "title" : "An Acceptable Time",
- "content" : "Cobalt",
- "image" : "https://www.lowell-rogahn.io:60654/#molestias",
- "createdAt" : "2024-01-18T18:43:04.779531",
- "updatedAt" : "2024-01-18T18:43:04.779548",
+ "title" : "The Green Bay Tree",
+ "content" : "Gold",
+ "image" : "https://www.andreas-waelchi.io:32924/",
+ "createdAt" : "2024-01-19T23:26:05.330447",
+ "updatedAt" : "2024-01-19T23:26:05.330461",
"temperatureArrange" : {
"min" : 0.0,
"max" : 15.0
},
- "likeCnt" : 54,
+ "likeCnt" : 93,
"isLike" : 0
}, {
- "postId" : 976739760,
+ "postId" : 411854187,
"writer" : {
- "userId" : 1468392497,
- "nickname" : "georgianne.yundt",
- "image" : "http://www.sherilyn-pollich.org/dolores?cumque=magnam&dolor=nulla#deleniti"
+ "userId" : 845471690,
+ "nickname" : "eugena.spencer",
+ "image" : "https://www.chance-quitzon.io/explicabo/quo?fugiat=nesciunt&sit=necessitatibus#dicta"
},
- "title" : "The Little Foxes",
- "content" : "Helium",
- "image" : "https://www.georgette-hirthe.net/aperiam/optio?eum=molestiae&aut=officiis#illum",
- "createdAt" : "2024-01-18T18:43:04.782134",
- "updatedAt" : "2024-01-18T18:43:04.78215",
+ "title" : "Ah, Wilderness!",
+ "content" : "Cesium",
+ "image" : "https://www.lauralee-lowe.info/odio/non?vel=culpa&autem=sit",
+ "createdAt" : "2024-01-19T23:26:05.334196",
+ "updatedAt" : "2024-01-19T23:26:05.334205",
"temperatureArrange" : {
"min" : 0.0,
"max" : 15.0
},
- "likeCnt" : 55,
+ "likeCnt" : 58,
"isLike" : 0
}, {
- "postId" : 1153411505,
+ "postId" : 1984546333,
"writer" : {
- "userId" : 682342469,
- "nickname" : "marlin.nienow",
- "image" : "https://www.darrick-kozey.io:61868/perspiciatis#quae"
+ "userId" : 1189354801,
+ "nickname" : "khalilah.kunze",
+ "image" : "https://www.rick-marquardt.info:65501/non/voluptatem"
},
- "title" : "Precious Bane",
- "content" : "Potassium",
- "image" : "http://www.corrine-west.biz/a/dolorem?sit=dolorem&molestias=aliquid",
- "createdAt" : "2024-01-18T18:43:04.78255",
- "updatedAt" : "2024-01-18T18:43:04.782565",
+ "title" : "Fair Stood the Wind for France",
+ "content" : "Lutetium",
+ "image" : "https://www.stephane-weber.co:62304/",
+ "createdAt" : "2024-01-19T23:26:05.334755",
+ "updatedAt" : "2024-01-19T23:26:05.334763",
"temperatureArrange" : {
"min" : 0.0,
"max" : 15.0
},
- "likeCnt" : 70,
+ "likeCnt" : 45,
"isLike" : 0
} ]
@@ -1845,61 +1845,61 @@ Respons
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
-Content-Length: 1566
+Content-Length: 1487
[ {
- "postId" : 1908042653,
+ "postId" : 391756997,
"writer" : {
- "userId" : 934467639,
- "nickname" : "alfredo.schmidt",
- "image" : "http://www.king-huels.com:45991/nemo/et?quas=vero&debitis=consequatur#ut"
+ "userId" : 563328115,
+ "nickname" : "kraig.waters",
+ "image" : "http://www.ethyl-rau.net/fuga#et"
},
- "title" : "An Acceptable Time",
- "content" : "Cobalt",
- "image" : "https://www.lowell-rogahn.io:60654/#molestias",
- "createdAt" : "2024-01-18T18:43:04.779531",
- "updatedAt" : "2024-01-18T18:43:04.779548",
+ "title" : "The Green Bay Tree",
+ "content" : "Gold",
+ "image" : "https://www.andreas-waelchi.io:32924/",
+ "createdAt" : "2024-01-19T23:26:05.330447",
+ "updatedAt" : "2024-01-19T23:26:05.330461",
"temperatureArrange" : {
"min" : 0.0,
"max" : 15.0
},
- "likeCnt" : 54,
+ "likeCnt" : 93,
"isLike" : 0
}, {
- "postId" : 976739760,
+ "postId" : 411854187,
"writer" : {
- "userId" : 1468392497,
- "nickname" : "georgianne.yundt",
- "image" : "http://www.sherilyn-pollich.org/dolores?cumque=magnam&dolor=nulla#deleniti"
+ "userId" : 845471690,
+ "nickname" : "eugena.spencer",
+ "image" : "https://www.chance-quitzon.io/explicabo/quo?fugiat=nesciunt&sit=necessitatibus#dicta"
},
- "title" : "The Little Foxes",
- "content" : "Helium",
- "image" : "https://www.georgette-hirthe.net/aperiam/optio?eum=molestiae&aut=officiis#illum",
- "createdAt" : "2024-01-18T18:43:04.782134",
- "updatedAt" : "2024-01-18T18:43:04.78215",
+ "title" : "Ah, Wilderness!",
+ "content" : "Cesium",
+ "image" : "https://www.lauralee-lowe.info/odio/non?vel=culpa&autem=sit",
+ "createdAt" : "2024-01-19T23:26:05.334196",
+ "updatedAt" : "2024-01-19T23:26:05.334205",
"temperatureArrange" : {
"min" : 0.0,
"max" : 15.0
},
- "likeCnt" : 55,
+ "likeCnt" : 58,
"isLike" : 0
}, {
- "postId" : 1153411505,
+ "postId" : 1984546333,
"writer" : {
- "userId" : 682342469,
- "nickname" : "marlin.nienow",
- "image" : "https://www.darrick-kozey.io:61868/perspiciatis#quae"
+ "userId" : 1189354801,
+ "nickname" : "khalilah.kunze",
+ "image" : "https://www.rick-marquardt.info:65501/non/voluptatem"
},
- "title" : "Precious Bane",
- "content" : "Potassium",
- "image" : "http://www.corrine-west.biz/a/dolorem?sit=dolorem&molestias=aliquid",
- "createdAt" : "2024-01-18T18:43:04.78255",
- "updatedAt" : "2024-01-18T18:43:04.782565",
+ "title" : "Fair Stood the Wind for France",
+ "content" : "Lutetium",
+ "image" : "https://www.stephane-weber.co:62304/",
+ "createdAt" : "2024-01-19T23:26:05.334755",
+ "updatedAt" : "2024-01-19T23:26:05.334763",
"temperatureArrange" : {
"min" : 0.0,
"max" : 15.0
},
- "likeCnt" : 70,
+ "likeCnt" : 45,
"isLike" : 0
} ]
@@ -2003,7 +2003,7 @@ Request
PUT /api/v1/posts/2 HTTP/1.1
Content-Type: multipart/form-data;charset=UTF-8; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
-Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJvb3R3IiwiaWF0IjoxNzA1NTcwOTg0LCJleHAiOjE3MDU1NzQ1ODQsInVzZXJfaWQiOjF9.mTcgBjKPrrKkjVtfmEk0MJyDI-8PQyKuXrzwr2w1_I8mwQq5lT6PkW9eMPNfCee2vdtxCj6HF_U2rN_yqcbgRA
+Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJvb3R3IiwiaWF0IjoxNzA1Njc0MzY1LCJleHAiOjE3MDU2Nzc5NjUsInVzZXJfaWQiOjF9.7YEbtfN90q-vWJ47IdoUy79KtHJdjSEjVn16sm4glP5UUzuJG705VSJR740ZlBdwKCn5AUDGnOPRpxwSeUC6aA
Accept: application/json
Host: docs.api.com
@@ -2011,7 +2011,7 @@ Request
Content-Disposition: form-data; name=request; filename=request.json
Content-Type: application/json
-{"title":"Absalom, Absalom!","content":"Neodymium"}
+{"title":"The Little Foxes","content":"Flerovium"}
--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
Content-Disposition: form-data; name=postImg; filename=image.jpeg
Content-Type: image/jpeg
@@ -2028,11 +2028,11 @@ Response
{
"postId" : 2,
- "title" : "Absalom, Absalom!",
- "content" : "Neodymium",
- "image" : "https://www.shelby-schaefer.name:21573/et/distinctiofugiat?magnam=consequatur&consectetur=doloremque#corrupti",
- "createdAt" : "2024-01-18T18:43:04.934907",
- "updatedAt" : "2024-01-18T18:43:04.934923",
+ "title" : "The Little Foxes",
+ "content" : "Flerovium",
+ "image" : "https://www.whitney-bogisich.org:25925/voluptas/sunt#reiciendis",
+ "createdAt" : "2024-01-19T23:26:05.741933",
+ "updatedAt" : "2024-01-19T23:26:05.741948",
"temperatureArrange" : {
"min" : 0.0,
"max" : 15.0
@@ -2106,15 +2106,15 @@ Respo
Vary: Access-Control-Request-Headers
Location: /api/v1/posts/2
Content-Type: application/json
-Content-Length: 361
+Content-Length: 314
{
"postId" : 2,
- "title" : "Absalom, Absalom!",
- "content" : "Neodymium",
- "image" : "https://www.shelby-schaefer.name:21573/et/distinctiofugiat?magnam=consequatur&consectetur=doloremque#corrupti",
- "createdAt" : "2024-01-18T18:43:04.934907",
- "updatedAt" : "2024-01-18T18:43:04.934923",
+ "title" : "The Little Foxes",
+ "content" : "Flerovium",
+ "image" : "https://www.whitney-bogisich.org:25925/voluptas/sunt#reiciendis",
+ "createdAt" : "2024-01-19T23:26:05.741933",
+ "updatedAt" : "2024-01-19T23:26:05.741948",
"temperatureArrange" : {
"min" : 0.0,
"max" : 15.0
@@ -2190,8 +2190,8 @@ Request H
Request example
-DELETE /api/v1/posts/1744803171 HTTP/1.1
-Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJvb3R3IiwiaWF0IjoxNzA1NTcwOTg0LCJleHAiOjE3MDU1NzQ1ODQsInVzZXJfaWQiOjF9.mTcgBjKPrrKkjVtfmEk0MJyDI-8PQyKuXrzwr2w1_I8mwQq5lT6PkW9eMPNfCee2vdtxCj6HF_U2rN_yqcbgRA
+DELETE /api/v1/posts/367321063 HTTP/1.1
+Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJvb3R3IiwiaWF0IjoxNzA1Njc0MzY1LCJleHAiOjE3MDU2Nzc5NjUsInVzZXJfaWQiOjF9.7YEbtfN90q-vWJ47IdoUy79KtHJdjSEjVn16sm4glP5UUzuJG705VSJR740ZlBdwKCn5AUDGnOPRpxwSeUC6aA
Host: docs.api.com
@@ -2256,7 +2256,7 @@ Request H
{
- "postId" : 1251693879
+ "postId" : 134978164
}
@@ -2286,15 +2286,15 @@ Request H
Request example
-POST /api/v1/posts/1251693879/likes HTTP/1.1
+POST /api/v1/posts/134978164/likes HTTP/1.1
Content-Type: application/json;charset=UTF-8
-Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJvb3R3IiwiaWF0IjoxNzA1NTcwOTgzLCJleHAiOjE3MDU1NzQ1ODMsInVzZXJfaWQiOjIxNDIzNzM3MjN9.soHfQaFbqHJl5xPC3moiDjk4fXWy9l0oTTliB9oSzqsfArjZKeBV5KuWtc_1cm4e1AO-PhBr2V4_m9h2Et_3vg
+Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJvb3R3IiwiaWF0IjoxNzA1Njc0MzYyLCJleHAiOjE3MDU2Nzc5NjIsInVzZXJfaWQiOjExMjQ5OTI2Mn0.PeuawdOnk4BzLdNZY9_Hi_yz_1M6Di1-DM_Y10aBgj_EM0So8KEMOFhF4sjY-Wod8IAAr6K4UCYLo3ZoYlChww
Accept: application/json
-Content-Length: 27
+Content-Length: 26
Host: docs.api.com
{
- "postId" : 1251693879
+ "postId" : 134978164
}
@@ -2305,9 +2305,9 @@ Response
{
- "likeId" : 581393781,
- "userId" : 2142373723,
- "postId" : 1251693879,
+ "likeId" : 2008964258,
+ "userId" : 112499262,
+ "postId" : 134978164,
"status" : true
}
@@ -2357,12 +2357,12 @@ Respo
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
-Content-Length: 95
+Content-Length: 94
{
- "likeId" : 581393781,
- "userId" : 2142373723,
- "postId" : 1251693879,
+ "likeId" : 2008964258,
+ "userId" : 112499262,
+ "postId" : 134978164,
"status" : true
}
@@ -2446,7 +2446,7 @@ Request
GET /api/v1/weather?nx=50&ny=127 HTTP/1.1
Content-Type: application/json;charset=UTF-8
-Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJvb3R3IiwiaWF0IjoxNzA1NTcwOTg3LCJleHAiOjE3MDU1NzQ1ODcsInVzZXJfaWQiOjF9.PXvjVy9boT_qqEC9Vt0SWy2OjUPPj3wbUtTJ5iUyh21-u3C9WfWh_gH2AvAqo3Cj6XWP0twgbUmBUlM_XYChFw
+Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJvb3R3IiwiaWF0IjoxNzA1Njc0MzcyLCJleHAiOjE3MDU2Nzc5NzIsInVzZXJfaWQiOjF9.lvIkeLYQpvhX-M6GBQHaKGBKXKRolg_UMSGNMdfGmGqn2qTSNFVYmETKa6xHMxroNHXtsTy-9DlnRaCALseZ-g
Accept: application/json
Host: docs.api.com
@@ -2528,7 +2528,7 @@ Respo
handleSaveException(SaveException e) {
return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY)
.body(errorResponse);
}
+
}
diff --git a/src/main/java/com/backendoori/ootw/common/image/exception/ImageException.java b/src/main/java/com/backendoori/ootw/image/exception/ImageException.java
similarity index 88%
rename from src/main/java/com/backendoori/ootw/common/image/exception/ImageException.java
rename to src/main/java/com/backendoori/ootw/image/exception/ImageException.java
index 2109c917..0f4be035 100644
--- a/src/main/java/com/backendoori/ootw/common/image/exception/ImageException.java
+++ b/src/main/java/com/backendoori/ootw/image/exception/ImageException.java
@@ -1,4 +1,4 @@
-package com.backendoori.ootw.common.image.exception;
+package com.backendoori.ootw.image.exception;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
diff --git a/src/main/java/com/backendoori/ootw/common/image/exception/SaveException.java b/src/main/java/com/backendoori/ootw/image/exception/SaveException.java
similarity index 84%
rename from src/main/java/com/backendoori/ootw/common/image/exception/SaveException.java
rename to src/main/java/com/backendoori/ootw/image/exception/SaveException.java
index 4ec98d5c..a3b647a5 100644
--- a/src/main/java/com/backendoori/ootw/common/image/exception/SaveException.java
+++ b/src/main/java/com/backendoori/ootw/image/exception/SaveException.java
@@ -1,4 +1,4 @@
-package com.backendoori.ootw.common.image.exception;
+package com.backendoori.ootw.image.exception;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
diff --git a/src/main/java/com/backendoori/ootw/image/repository/ImageRepository.java b/src/main/java/com/backendoori/ootw/image/repository/ImageRepository.java
new file mode 100644
index 00000000..2fe3e51f
--- /dev/null
+++ b/src/main/java/com/backendoori/ootw/image/repository/ImageRepository.java
@@ -0,0 +1,8 @@
+package com.backendoori.ootw.image.repository;
+
+import com.backendoori.ootw.image.domain.Image;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface ImageRepository extends JpaRepository {
+
+}
diff --git a/src/main/java/com/backendoori/ootw/common/image/ImageService.java b/src/main/java/com/backendoori/ootw/image/service/ImageService.java
similarity index 64%
rename from src/main/java/com/backendoori/ootw/common/image/ImageService.java
rename to src/main/java/com/backendoori/ootw/image/service/ImageService.java
index 1064f453..0a6e5a17 100644
--- a/src/main/java/com/backendoori/ootw/common/image/ImageService.java
+++ b/src/main/java/com/backendoori/ootw/image/service/ImageService.java
@@ -1,5 +1,6 @@
-package com.backendoori.ootw.common.image;
+package com.backendoori.ootw.image.service;
+import com.backendoori.ootw.image.dto.ImageFile;
import org.springframework.web.multipart.MultipartFile;
public interface ImageService {
diff --git a/src/main/java/com/backendoori/ootw/image/service/ImageUpdateService.java b/src/main/java/com/backendoori/ootw/image/service/ImageUpdateService.java
new file mode 100644
index 00000000..1fe6ab52
--- /dev/null
+++ b/src/main/java/com/backendoori/ootw/image/service/ImageUpdateService.java
@@ -0,0 +1,55 @@
+package com.backendoori.ootw.image.service;
+
+import java.util.ArrayList;
+import java.util.List;
+import com.backendoori.ootw.avatar.domain.AvatarItem;
+import com.backendoori.ootw.avatar.repository.AvatarItemRepository;
+import com.backendoori.ootw.image.domain.Image;
+import com.backendoori.ootw.image.repository.ImageRepository;
+import com.backendoori.ootw.post.domain.Post;
+import com.backendoori.ootw.post.repository.PostRepository;
+import jakarta.transaction.Transactional;
+import lombok.RequiredArgsConstructor;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class ImageUpdateService {
+
+ private final PostRepository postRepository;
+ private final AvatarItemRepository avatarItemRepository;
+ private final ImageRepository imageRepository;
+ private final ImageService imageService;
+ public static final String TIMEZONE = "Asia/Seoul";
+ public static final String CRON = "0 20 00 10 * ?";
+
+ @Scheduled(cron = CRON, zone = TIMEZONE) // 매월 20일 오전 00시 10분에 실행
+ @Async
+ @Transactional
+ public void deleteUnused(){
+
+ List urls = new ArrayList<>();
+
+ postRepository.findAll()
+ .stream()
+ .map(Post::getImageUrl)
+ .forEach(urls::add);
+
+ avatarItemRepository.findAll()
+ .stream()
+ .map(AvatarItem::getImageUrl)
+ .forEach(urls::add);
+
+ List images = imageRepository.findAll();
+
+ for(Image image : images){
+ if(!urls.contains(image.getImageUrl())){
+ imageService.delete(image.getFileName());
+ }
+ }
+
+ }
+
+}
diff --git a/src/main/java/com/backendoori/ootw/common/image/MiniOImageServiceImpl.java b/src/main/java/com/backendoori/ootw/image/service/MiniOImageServiceImpl.java
similarity index 52%
rename from src/main/java/com/backendoori/ootw/common/image/MiniOImageServiceImpl.java
rename to src/main/java/com/backendoori/ootw/image/service/MiniOImageServiceImpl.java
index 5dee94e9..959dc883 100644
--- a/src/main/java/com/backendoori/ootw/common/image/MiniOImageServiceImpl.java
+++ b/src/main/java/com/backendoori/ootw/image/service/MiniOImageServiceImpl.java
@@ -1,21 +1,26 @@
-package com.backendoori.ootw.common.image;
+package com.backendoori.ootw.image.service;
-import static com.backendoori.ootw.common.image.exception.ImageException.IMAGE_ROLLBACK_FAIL_MESSAGE;
-import static com.backendoori.ootw.common.image.exception.ImageException.IMAGE_UPLOAD_FAIL_MESSAGE;
-import static com.backendoori.ootw.common.validation.ImageValidator.validateImage;
+import static com.backendoori.ootw.image.validation.ImageValidator.validateImage;
import java.io.InputStream;
-import java.nio.file.Path;
+import java.util.UUID;
import java.util.concurrent.TimeUnit;
-import com.backendoori.ootw.common.image.exception.ImageException;
+import com.backendoori.ootw.image.domain.Image;
+import com.backendoori.ootw.image.dto.ImageFile;
+import com.backendoori.ootw.image.exception.ImageException;
import com.backendoori.ootw.config.MiniOConfig;
+import com.backendoori.ootw.image.repository.ImageRepository;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import io.minio.http.Method;
+import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@@ -29,28 +34,46 @@ public class MiniOImageServiceImpl implements ImageService {
private final MinioClient minioClient;
private final MiniOConfig miniOConfig;
- private Path path;
+ private final ImageRepository imageRepository;
@Override
public ImageFile upload(MultipartFile file) {
validateImage(file);
+ String randomFileName = getUniqueFileName(file);
try {
- path = Path.of(file.getOriginalFilename());
InputStream inputStream = file.getInputStream();
String contentType = file.getContentType();
PutObjectArgs args = PutObjectArgs.builder()
.bucket(miniOConfig.getBucket())
- .object(path.toString())
+ .object(randomFileName)
.stream(inputStream, inputStream.available(), -1)
.contentType(contentType)
.build();
minioClient.putObject(args);
- return new ImageFile(getUrl(), path.toString());
+ String url = getUrl(randomFileName);
+ Image image = saveImage(url, randomFileName);
+ imageRepository.save(image);
+ return ImageFile.from(image);
} catch (Exception e) {
- throw new ImageException(IMAGE_UPLOAD_FAIL_MESSAGE);
+ throw new ImageException(ImageException.IMAGE_UPLOAD_FAIL_MESSAGE);
}
}
+ private static Image saveImage(String url, String randomFileName) {
+ return Image.builder()
+ .ImageUrl(url)
+ .fileName(randomFileName)
+ .build();
+ }
+
+ @NotNull
+ private static String getUniqueFileName(MultipartFile file) {
+ String randomUUID = UUID.randomUUID().toString();
+ String originalFileName = file.getOriginalFilename();
+
+ return randomUUID + originalFileName;
+ }
+
@Override
public void delete(String fileName) {
try {
@@ -59,21 +82,21 @@ public void delete(String fileName) {
.object(fileName)
.build());
} catch (Exception e) {
- throw new ImageException(IMAGE_ROLLBACK_FAIL_MESSAGE);
+ throw new ImageException(ImageException.IMAGE_ROLLBACK_FAIL_MESSAGE);
}
}
- private String getUrl() {
+ private String getUrl(String fileName) {
try {
return minioClient.getPresignedObjectUrl(
GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(miniOConfig.getBucket())
- .object(path.toString())
+ .object(fileName)
.expiry(DURATION, TimeUnit.HOURS)
.build());
} catch (Exception e) {
- throw new ImageException(IMAGE_UPLOAD_FAIL_MESSAGE);
+ throw new ImageException(ImageException.IMAGE_UPLOAD_FAIL_MESSAGE);
}
}
diff --git a/src/main/java/com/backendoori/ootw/image/validation/Enum.java b/src/main/java/com/backendoori/ootw/image/validation/Enum.java
new file mode 100644
index 00000000..00cc7084
--- /dev/null
+++ b/src/main/java/com/backendoori/ootw/image/validation/Enum.java
@@ -0,0 +1,20 @@
+package com.backendoori.ootw.image.validation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import jakarta.validation.Constraint;
+import jakarta.validation.Payload;
+
+@Target(value = {ElementType.PARAMETER, ElementType.FIELD})
+@Retention(value = RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = EnumValidator.class)
+public @interface Enum {
+
+ String message() default "유효하지 않은 값입니다 다시 입력해주세요";
+ Class>[] groups() default {};
+ Class extends Payload>[] payload() default {};
+ Class extends java.lang.Enum>> enumClass();
+
+}
diff --git a/src/main/java/com/backendoori/ootw/image/validation/EnumValidator.java b/src/main/java/com/backendoori/ootw/image/validation/EnumValidator.java
new file mode 100644
index 00000000..72a966b4
--- /dev/null
+++ b/src/main/java/com/backendoori/ootw/image/validation/EnumValidator.java
@@ -0,0 +1,26 @@
+package com.backendoori.ootw.image.validation;
+
+import java.util.Arrays;
+import jakarta.validation.ConstraintValidator;
+import jakarta.validation.ConstraintValidatorContext;
+
+public class EnumValidator implements ConstraintValidator {
+
+ private Enum annotation;
+
+ @Override
+ public void initialize(Enum constraintAnnotation) {
+ this.annotation = constraintAnnotation;
+ }
+
+ @Override
+ public boolean isValid(String type, ConstraintValidatorContext context) {
+ if (type == null) {
+ return false;
+ }
+
+ return Arrays.stream(this.annotation.enumClass().getEnumConstants())
+ .anyMatch(e -> e.name().equals(type));
+ }
+
+}
diff --git a/src/main/java/com/backendoori/ootw/common/validation/Image.java b/src/main/java/com/backendoori/ootw/image/validation/Image.java
similarity index 93%
rename from src/main/java/com/backendoori/ootw/common/validation/Image.java
rename to src/main/java/com/backendoori/ootw/image/validation/Image.java
index 23ccc5dc..71719824 100644
--- a/src/main/java/com/backendoori/ootw/common/validation/Image.java
+++ b/src/main/java/com/backendoori/ootw/image/validation/Image.java
@@ -1,4 +1,4 @@
-package com.backendoori.ootw.common.validation;
+package com.backendoori.ootw.image.validation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/src/main/java/com/backendoori/ootw/common/validation/ImageAnnotationValidator.java b/src/main/java/com/backendoori/ootw/image/validation/ImageAnnotationValidator.java
similarity index 95%
rename from src/main/java/com/backendoori/ootw/common/validation/ImageAnnotationValidator.java
rename to src/main/java/com/backendoori/ootw/image/validation/ImageAnnotationValidator.java
index e6db8849..db677131 100644
--- a/src/main/java/com/backendoori/ootw/common/validation/ImageAnnotationValidator.java
+++ b/src/main/java/com/backendoori/ootw/image/validation/ImageAnnotationValidator.java
@@ -1,4 +1,4 @@
-package com.backendoori.ootw.common.validation;
+package com.backendoori.ootw.image.validation;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
diff --git a/src/main/java/com/backendoori/ootw/common/validation/ImageValidator.java b/src/main/java/com/backendoori/ootw/image/validation/ImageValidator.java
similarity index 95%
rename from src/main/java/com/backendoori/ootw/common/validation/ImageValidator.java
rename to src/main/java/com/backendoori/ootw/image/validation/ImageValidator.java
index d32e4e35..07172a72 100644
--- a/src/main/java/com/backendoori/ootw/common/validation/ImageValidator.java
+++ b/src/main/java/com/backendoori/ootw/image/validation/ImageValidator.java
@@ -1,4 +1,4 @@
-package com.backendoori.ootw.common.validation;
+package com.backendoori.ootw.image.validation;
import io.jsonwebtoken.lang.Assert;
import lombok.AccessLevel;
diff --git a/src/main/java/com/backendoori/ootw/post/controller/PostController.java b/src/main/java/com/backendoori/ootw/post/controller/PostController.java
index 91946cb6..4be1c93b 100644
--- a/src/main/java/com/backendoori/ootw/post/controller/PostController.java
+++ b/src/main/java/com/backendoori/ootw/post/controller/PostController.java
@@ -2,7 +2,7 @@
import java.net.URI;
import java.util.List;
-import com.backendoori.ootw.common.validation.Image;
+import com.backendoori.ootw.image.validation.Image;
import com.backendoori.ootw.post.dto.request.PostSaveRequest;
import com.backendoori.ootw.post.dto.request.PostUpdateRequest;
import com.backendoori.ootw.post.dto.response.PostReadResponse;
diff --git a/src/main/java/com/backendoori/ootw/post/service/PostService.java b/src/main/java/com/backendoori/ootw/post/service/PostService.java
index b16e643c..8d641b38 100644
--- a/src/main/java/com/backendoori/ootw/post/service/PostService.java
+++ b/src/main/java/com/backendoori/ootw/post/service/PostService.java
@@ -7,9 +7,9 @@
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
-import com.backendoori.ootw.common.image.ImageFile;
-import com.backendoori.ootw.common.image.ImageService;
-import com.backendoori.ootw.common.image.exception.SaveException;
+import com.backendoori.ootw.image.dto.ImageFile;
+import com.backendoori.ootw.image.service.ImageService;
+import com.backendoori.ootw.image.exception.SaveException;
import com.backendoori.ootw.exception.PermissionException;
import com.backendoori.ootw.exception.UserNotFoundException;
import com.backendoori.ootw.like.domain.Like;
diff --git a/src/test/java/com/backendoori/ootw/avatar/controller/AvatarItemControllerTest.java b/src/test/java/com/backendoori/ootw/avatar/controller/AvatarItemControllerTest.java
index bc366268..417607da 100644
--- a/src/test/java/com/backendoori/ootw/avatar/controller/AvatarItemControllerTest.java
+++ b/src/test/java/com/backendoori/ootw/avatar/controller/AvatarItemControllerTest.java
@@ -8,16 +8,19 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.nio.charset.StandardCharsets;
+import java.util.stream.Stream;
import com.backendoori.ootw.avatar.domain.Sex;
import com.backendoori.ootw.avatar.dto.AvatarItemRequest;
import com.backendoori.ootw.avatar.repository.AvatarItemRepository;
import com.backendoori.ootw.avatar.service.AvatarItemService;
-import com.backendoori.ootw.common.image.exception.ImageException;
-import com.backendoori.ootw.common.image.exception.SaveException;
+import com.backendoori.ootw.image.exception.ImageException;
+import com.backendoori.ootw.image.exception.SaveException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.NullAndEmptySource;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
@@ -67,6 +70,27 @@ public void imageUploadTest() throws Exception {
.andExpect(status().isCreated());
}
+ @ParameterizedTest
+ @MethodSource("provideInvalidAvatarImageInfo")
+ @DisplayName("아바타 이미지를 등록 시 ItemRequest 가 잘못되면 예외가 발생한다.")
+ public void imageUploadFailWithInvalidItemRequest(String itemType, String sex) throws Exception {
+ //given
+ MockMultipartFile file = new MockMultipartFile("file", "filename.txt",
+ "image/jpeg", "some xml".getBytes());
+ AvatarItemRequest requestDto = new AvatarItemRequest(itemType, sex);
+ MockMultipartFile request = new MockMultipartFile("request", "filename.txt",
+ "application/json", objectMapper.writeValueAsBytes(requestDto));
+
+ //when, then
+ mockMvc.perform(multipart("/api/v1/avatar-items")
+ .file(file)
+ .file(request)
+ .contentType(MediaType.MULTIPART_FORM_DATA)
+ .accept(MediaType.APPLICATION_JSON)
+ .characterEncoding(StandardCharsets.UTF_8))
+ .andExpect(status().isBadRequest());
+ }
+
@Test
@DisplayName("아바타 등록 요청 중 이미지 등록 중 예외가 발생하면 커스텀 예외가 발생한다.")
public void imageUploadException() throws Exception {
@@ -185,4 +209,19 @@ public void getItemList() throws Exception {
.andExpect(status().isOk())
.andDo(print());
}
+
+ static Stream provideInvalidAvatarImageInfo() {
+ String validType = "HAIR";
+ String validSex = "MALE";
+ return java.util.stream.Stream.of(
+ Arguments.of(null, validSex),
+ Arguments.of(validType, null),
+ Arguments.of("", validSex),
+ Arguments.of(validType, ""),
+ Arguments.of(" ", validSex),
+ Arguments.of(validType, " "),
+ Arguments.of("hair", validSex),
+ Arguments.of(validType, "female")
+ );
+ }
}
diff --git a/src/test/java/com/backendoori/ootw/avatar/service/AvatarItemServiceTest.java b/src/test/java/com/backendoori/ootw/avatar/service/AvatarItemServiceTest.java
index 9aa81dcc..7e6d60a6 100644
--- a/src/test/java/com/backendoori/ootw/avatar/service/AvatarItemServiceTest.java
+++ b/src/test/java/com/backendoori/ootw/avatar/service/AvatarItemServiceTest.java
@@ -10,7 +10,7 @@
import com.backendoori.ootw.avatar.dto.AvatarItemRequest;
import com.backendoori.ootw.avatar.dto.AvatarItemResponse;
import com.backendoori.ootw.avatar.repository.AvatarItemRepository;
-import com.backendoori.ootw.common.image.exception.SaveException;
+import com.backendoori.ootw.image.exception.SaveException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
diff --git a/src/test/java/com/backendoori/ootw/common/image/MiniOImageServiceImplTest.java b/src/test/java/com/backendoori/ootw/common/image/MiniOImageServiceImplTest.java
index b4ba4816..983cdc4d 100644
--- a/src/test/java/com/backendoori/ootw/common/image/MiniOImageServiceImplTest.java
+++ b/src/test/java/com/backendoori/ootw/common/image/MiniOImageServiceImplTest.java
@@ -7,7 +7,9 @@
import static org.mockito.Mockito.when;
import java.util.stream.Stream;
-import com.backendoori.ootw.common.image.exception.ImageException;
+import com.backendoori.ootw.image.service.ImageService;
+import com.backendoori.ootw.image.service.MiniOImageServiceImpl;
+import com.backendoori.ootw.image.exception.ImageException;
import com.backendoori.ootw.config.MiniOConfig;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
diff --git a/src/test/java/com/backendoori/ootw/post/service/PostServiceTest.java b/src/test/java/com/backendoori/ootw/post/service/PostServiceTest.java
index 59f913a5..765be6e0 100644
--- a/src/test/java/com/backendoori/ootw/post/service/PostServiceTest.java
+++ b/src/test/java/com/backendoori/ootw/post/service/PostServiceTest.java
@@ -20,9 +20,9 @@
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.stream.Stream;
-import com.backendoori.ootw.common.image.ImageFile;
-import com.backendoori.ootw.common.image.ImageService;
-import com.backendoori.ootw.common.image.exception.SaveException;
+import com.backendoori.ootw.image.dto.ImageFile;
+import com.backendoori.ootw.image.service.ImageService;
+import com.backendoori.ootw.image.exception.SaveException;
import com.backendoori.ootw.exception.PermissionException;
import com.backendoori.ootw.exception.UserNotFoundException;
import com.backendoori.ootw.like.repository.LikeRepository;
diff --git a/src/main/java/com/backendoori/ootw/OotwApplication.java b/src/main/java/com/backendoori/ootw/OotwApplication.java
index d1869f36..93d4312b 100644
--- a/src/main/java/com/backendoori/ootw/OotwApplication.java
+++ b/src/main/java/com/backendoori/ootw/OotwApplication.java
@@ -5,7 +5,9 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
+import org.springframework.scheduling.annotation.EnableScheduling;
+@EnableScheduling
@SpringBootApplication
@ConfigurationPropertiesScan
public class OotwApplication {
diff --git a/src/main/java/com/backendoori/ootw/avatar/controller/AvatarItemController.java b/src/main/java/com/backendoori/ootw/avatar/controller/AvatarItemController.java
index 6e0c4c1b..0785a06a 100644
--- a/src/main/java/com/backendoori/ootw/avatar/controller/AvatarItemController.java
+++ b/src/main/java/com/backendoori/ootw/avatar/controller/AvatarItemController.java
@@ -4,7 +4,7 @@
import com.backendoori.ootw.avatar.dto.AvatarItemRequest;
import com.backendoori.ootw.avatar.dto.AvatarItemResponse;
import com.backendoori.ootw.avatar.service.AvatarItemService;
-import com.backendoori.ootw.common.validation.Image;
+import com.backendoori.ootw.image.validation.Image;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
diff --git a/src/main/java/com/backendoori/ootw/avatar/dto/AvatarItemRequest.java b/src/main/java/com/backendoori/ootw/avatar/dto/AvatarItemRequest.java
index 6285c895..3ec5e1ea 100644
--- a/src/main/java/com/backendoori/ootw/avatar/dto/AvatarItemRequest.java
+++ b/src/main/java/com/backendoori/ootw/avatar/dto/AvatarItemRequest.java
@@ -3,7 +3,6 @@
import com.backendoori.ootw.avatar.domain.ItemType;
import com.backendoori.ootw.avatar.domain.Sex;
import com.backendoori.ootw.common.validation.Enum;
-import jakarta.validation.constraints.NotNull;
public record AvatarItemRequest(
@Enum(enumClass = ItemType.class)
diff --git a/src/main/java/com/backendoori/ootw/avatar/service/AvatarItemService.java b/src/main/java/com/backendoori/ootw/avatar/service/AvatarItemService.java
index b66b0ff1..94d9bbcb 100644
--- a/src/main/java/com/backendoori/ootw/avatar/service/AvatarItemService.java
+++ b/src/main/java/com/backendoori/ootw/avatar/service/AvatarItemService.java
@@ -5,9 +5,9 @@
import com.backendoori.ootw.avatar.dto.AvatarItemRequest;
import com.backendoori.ootw.avatar.dto.AvatarItemResponse;
import com.backendoori.ootw.avatar.repository.AvatarItemRepository;
-import com.backendoori.ootw.common.image.ImageFile;
-import com.backendoori.ootw.common.image.ImageService;
-import com.backendoori.ootw.common.image.exception.SaveException;
+import com.backendoori.ootw.image.dto.ImageFile;
+import com.backendoori.ootw.image.service.ImageService;
+import com.backendoori.ootw.image.exception.SaveException;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
diff --git a/src/main/java/com/backendoori/ootw/common/image/ImageFile.java b/src/main/java/com/backendoori/ootw/common/image/ImageFile.java
deleted file mode 100644
index 1aabf702..00000000
--- a/src/main/java/com/backendoori/ootw/common/image/ImageFile.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.backendoori.ootw.common.image;
-
-public record ImageFile(
- String url,
- String fileName
-) {
-
-}
diff --git a/src/main/java/com/backendoori/ootw/image/domain/Image.java b/src/main/java/com/backendoori/ootw/image/domain/Image.java
new file mode 100644
index 00000000..2470f6cf
--- /dev/null
+++ b/src/main/java/com/backendoori/ootw/image/domain/Image.java
@@ -0,0 +1,33 @@
+package com.backendoori.ootw.image.domain;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.Table;
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Table(name = "images")
+@Getter
+@Entity
+@Builder
+@AllArgsConstructor(access = AccessLevel.PRIVATE)
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+public class Image {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @Column(name = "image_url", unique = true)
+ private String ImageUrl;
+
+ @Column(name = "filename")
+ private String fileName;
+
+}
diff --git a/src/main/java/com/backendoori/ootw/image/dto/ImageFile.java b/src/main/java/com/backendoori/ootw/image/dto/ImageFile.java
new file mode 100644
index 00000000..2e2a3cca
--- /dev/null
+++ b/src/main/java/com/backendoori/ootw/image/dto/ImageFile.java
@@ -0,0 +1,12 @@
+package com.backendoori.ootw.image.dto;
+
+import com.backendoori.ootw.image.domain.Image;
+
+public record ImageFile(
+ String url,
+ String fileName
+) {
+ public static ImageFile from(Image image){
+ return new ImageFile(image.getImageUrl(), image.getFileName());
+ }
+}
diff --git a/src/main/java/com/backendoori/ootw/common/image/exception/ImageControllerAdvice.java b/src/main/java/com/backendoori/ootw/image/exception/ImageControllerAdvice.java
similarity index 87%
rename from src/main/java/com/backendoori/ootw/common/image/exception/ImageControllerAdvice.java
rename to src/main/java/com/backendoori/ootw/image/exception/ImageControllerAdvice.java
index 91a9b179..ac74aafc 100644
--- a/src/main/java/com/backendoori/ootw/common/image/exception/ImageControllerAdvice.java
+++ b/src/main/java/com/backendoori/ootw/image/exception/ImageControllerAdvice.java
@@ -1,7 +1,9 @@
-package com.backendoori.ootw.common.image.exception;
+package com.backendoori.ootw.image.exception;
import com.backendoori.ootw.exception.ErrorResponse;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
@@ -9,6 +11,7 @@
@Slf4j
@RestControllerAdvice
+@Order(Ordered.HIGHEST_PRECEDENCE)
public class ImageControllerAdvice {
private static final String IMAGE_RELATED_EXCEPTION = "업로드 요청 중 문제가 발생했습니다.";
@@ -30,4 +33,5 @@ public ResponseEntity