κ²μν(Board), κ²μκΈ(Post), λκΈ(Comment) APIμ
λλ€. νκ΅λ³ κ²μν μμ±, κ²μκΈ μμ±/μ‘°ν, λκΈ κ΄λ¦¬ κΈ°λ₯μ μ 곡ν©λλ€.
λΌμ°νΈ νμΌ : backend/src/routes/boards.js, backend/src/routes/posts.js, backend/src/routes/comments.js
컨νΈλ‘€λ¬ νμΌ : backend/src/controllers/boards.js, backend/src/controllers/posts.js, backend/src/controllers/comments.js
λͺ¨λΈ νμΌ : backend/src/models/Board.js, backend/src/models/Post.js, backend/src/models/Comment.js
λ©μλ
κ²½λ‘
μ€λͺ
κΆν
POST
/api/boards
κ²μν μμ±
admin|manager
GET
/api/boards/:_id
κ²μν μ‘°ν
λ‘κ·ΈμΈ + μ½κΈ° κΆν
GET
/api/boards?school=
κ²μν λͺ©λ‘
λ‘κ·ΈμΈ
PUT
/api/boards/:_id
κ²μν μμ
admin|manager
PUT
/api/boards/:_id/permission/:type
κΆν μμ
admin|manager
POST
/api/boards/:_id/permission/:type/exceptions
κΆν μμΈ μΆκ°
admin|manager
DELETE
/api/boards/:_id/permission/:type/exceptions?userId=
κΆν μμΈ μμ
admin|manager
DELETE
/api/boards/:_id
κ²μν μμ
admin|manager
λ©μλ
κ²½λ‘
μ€λͺ
κΆν
POST
/api/posts
κ²μκΈ μμ±
λ‘κ·ΈμΈ + μ°κΈ° κΆν
GET
/api/posts/:_id
κ²μκΈ μ‘°ν
λ‘κ·ΈμΈ + μ½κΈ° κΆν
GET
/api/posts?board=&limit=&before=
κ²μκΈ λͺ©λ‘
λ‘κ·ΈμΈ + μ½κΈ° κΆν
PUT
/api/posts/:_id
κ²μκΈ μμ
λ‘κ·ΈμΈ (μμ±μ λλ κ΄λ¦¬μ)
PUT
/api/posts/:_id/pin
κ²μκΈ κ³ μ
admin|manager
DELETE
/api/posts/:_id
κ²μκΈ μμ
λ‘κ·ΈμΈ (μμ±μ λλ κ΄λ¦¬μ)
λκΈ (Comment)
λ©μλ
κ²½λ‘
μ€λͺ
κΆν
POST
/api/comments
λκΈ μμ±
λ‘κ·ΈμΈ + λκΈ κΆν
GET
/api/comments?post=
λκΈ λͺ©λ‘
λ‘κ·ΈμΈ + μ½κΈ° κΆν
PUT
/api/comments/:_id
λκΈ μμ
λ‘κ·ΈμΈ (μμ±μ λλ κ΄λ¦¬μ)
DELETE
/api/comments/:_id
λκΈ μμ
λ‘κ·ΈμΈ (μμ±μ λλ κ΄λ¦¬μ)
κ²μνμ μμ±ν©λλ€. κ²μν μ΄λ¦μ κΈ°λ°μΌλ‘ URL μ¬λ¬κ·Έκ° μλ μμ±λλ©°, κ°μ νκ΅ λ΄μμ μ¬λ¬κ·Έκ° μ€λ³΅λ μ μμ΅λλ€.
κΆν : admin λλ manager (isAdManager)
νλ
νμ
νμ
μ€λͺ
school
string
O
νκ΅ _id
name
string
O
κ²μν μ΄λ¦
description
string
X
κ²μν μ€λͺ
permissionWrite
object
X
μ°κΈ° κΆν μ€μ (κΈ°λ³Έ: κ΄λ¦¬μ+κ΅μ¬)
permissionRead
object
X
μ½κΈ° κΆν μ€μ (κΈ°λ³Έ: μ 체)
{
"school" : " 507f1f77bcf86cd799439011" ,
"name" : " μμ κ²μν" ,
"description" : " μμ λ‘κ² κΈμ μμ±ν μ μλ κ²μνμ
λλ€." ,
"permissionWrite" : {
"manager" : true ,
"teacher" : true ,
"student" : true ,
"exceptions" : []
},
"permissionRead" : {
"manager" : true ,
"teacher" : true ,
"student" : true ,
"exceptions" : []
}
}
{
"board" : {
"_id" : " 507f1f77bcf86cd799439022" ,
"school" : " 507f1f77bcf86cd799439011" ,
"schoolId" : " school-01" ,
"schoolName" : " ν
μ€νΈ νκ΅" ,
"name" : " μμ κ²μν" ,
"slug" : " μμ κ²μν" ,
"description" : " μμ λ‘κ² κΈμ μμ±ν μ μλ κ²μνμ
λλ€." ,
"creator" : " 507f1f77bcf86cd799439033" ,
"creatorId" : " admin01" ,
"creatorName" : " κ΄λ¦¬μ" ,
"permissionWrite" : {
"manager" : true ,
"teacher" : true ,
"student" : true ,
"exceptions" : []
},
"permissionRead" : {
"manager" : true ,
"teacher" : true ,
"student" : true ,
"exceptions" : []
},
"permissionComment" : {
"manager" : true ,
"teacher" : true ,
"student" : true ,
"exceptions" : []
},
"isDefault" : false ,
"isActive" : true ,
"order" : 0 ,
"postCount" : 0 ,
"createdAt" : " 2024-03-15T09:00:00.000Z" ,
"updatedAt" : " 2024-03-15T09:00:00.000Z"
}
}
μν μ½λ
λ©μμ§
μ€λͺ
400
FIELD_REQUIRED({νλλͺ
})
νμ νλ λλ½ (school, name)
404
__NOT_FOUND(school)
νκ΅λ₯Ό μ°Ύμ μ μμ
409
FIELD_IN_USE(board)
κ°μ νκ΅ λ΄ μ€λ³΅ μ¬λ¬κ·Έ
κ²μνμ λ¨μΌ λλ λͺ©λ‘μΌλ‘ μ‘°νν©λλ€. λͺ©λ‘ μ‘°ν μ κΈ°λ³Έ κ²μν(곡μ§μ¬ν)μ΄ μμΌλ©΄ μλ μμ±λ©λλ€.
κΆν : λ‘κ·ΈμΈ (isLoggedIn) + μ½κΈ° κΆν νμΈ
νλΌλ―Έν°
νμ
μ€λͺ
_id
string
κ²μν _id
{
"board" : {
"_id" : " 507f1f77bcf86cd799439022" ,
"school" : " 507f1f77bcf86cd799439011" ,
"schoolId" : " school-01" ,
"schoolName" : " ν
μ€νΈ νκ΅" ,
"name" : " 곡μ§μ¬ν" ,
"slug" : " announcements" ,
"description" : " νκ΅ κ³΅μ§μ¬νμ
λλ€." ,
"permissionWrite" : {
"manager" : true ,
"teacher" : true ,
"student" : false ,
"exceptions" : []
},
"permissionRead" : {
"manager" : true ,
"teacher" : true ,
"student" : true ,
"exceptions" : []
},
"permissionComment" : {
"manager" : true ,
"teacher" : true ,
"student" : true ,
"exceptions" : []
},
"isDefault" : true ,
"isActive" : true ,
"order" : 0 ,
"postCount" : 15 ,
"createdAt" : " 2024-01-01T09:00:00.000Z" ,
"updatedAt" : " 2024-03-15T09:00:00.000Z"
}
}
GET /api/boards?school={school._id}
κΆν : λ‘κ·ΈμΈ (isLoggedIn)
μ°Έκ³ : ν΄λΉ νκ΅μ κΈ°λ³Έ κ²μν(곡μ§μ¬ν)μ΄ μλ κ²½μ° μλμΌλ‘ μμ±λ©λλ€. μ½κΈ° κΆνμ΄ μλ κ²μνλ§ λ°νλ©λλ€.
νλΌλ―Έν°
νμ
νμ
μ€λͺ
school
string
O
νκ΅ _id
{
"boards" : [
{
"_id" : " 507f1f77bcf86cd799439022" ,
"name" : " 곡μ§μ¬ν" ,
"slug" : " announcements" ,
"description" : " νκ΅ κ³΅μ§μ¬νμ
λλ€." ,
"isDefault" : true ,
"isActive" : true ,
"order" : 0 ,
"postCount" : 15 ,
"permissionWrite" : { "manager" : true , "teacher" : true , "student" : false , "exceptions" : [] },
"permissionRead" : { "manager" : true , "teacher" : true , "student" : true , "exceptions" : [] },
"permissionComment" : { "manager" : true , "teacher" : true , "student" : true , "exceptions" : [] }
},
{
"_id" : " 507f1f77bcf86cd799439023" ,
"name" : " μμ κ²μν" ,
"slug" : " μμ κ²μν" ,
"description" : " " ,
"isDefault" : false ,
"isActive" : true ,
"order" : 1 ,
"postCount" : 42 ,
"permissionWrite" : { "manager" : true , "teacher" : true , "student" : true , "exceptions" : [] },
"permissionRead" : { "manager" : true , "teacher" : true , "student" : true , "exceptions" : [] },
"permissionComment" : { "manager" : true , "teacher" : true , "student" : true , "exceptions" : [] }
}
]
}
μν μ½λ
λ©μμ§
μ€λͺ
400
FIELD_REQUIRED(school)
λͺ©λ‘ μ‘°ν μ school νλΌλ―Έν° λλ½
403
PERMISSION_DENIED
μ½κΈ° κΆν μμ
404
__NOT_FOUND(board)
κ²μνμ μ°Ύμ μ μμ
404
__NOT_FOUND(school)
νκ΅λ₯Ό μ°Ύμ μ μμ
κ²μνμ μ΄λ¦, μ€λͺ
, μ λ ¬ μμλ₯Ό μμ ν©λλ€. κΈ°λ³Έ κ²μν(곡μ§μ¬ν)μ μ΄λ¦μ λ³κ²½ν μ μμ΅λλ€.
κΆν : admin λλ manager (isAdManager)
νλΌλ―Έν°
νμ
μ€λͺ
_id
string
κ²μν _id
νλ
νμ
νμ
μ€λͺ
name
string
X
κ²μν μ΄λ¦ (κΈ°λ³Έ κ²μνμ λ³κ²½ λΆκ°)
description
string
X
κ²μν μ€λͺ
order
number
X
μ λ ¬ μμ
{
"name" : " μμ κ²μν" ,
"description" : " μμ λ μ€λͺ
μ
λλ€." ,
"order" : 2
}
{
"board" : {
"_id" : " 507f1f77bcf86cd799439023" ,
"name" : " μμ κ²μν" ,
"description" : " μμ λ μ€λͺ
μ
λλ€." ,
"order" : 2
}
}
μν μ½λ
λ©μμ§
μ€λͺ
400
κΈ°λ³Έ κ²μνμ μ΄λ¦μ λ³κ²½ν μ μμ΅λλ€.
κΈ°λ³Έ κ²μν μ΄λ¦ λ³κ²½ μλ
404
__NOT_FOUND(board)
κ²μνμ μ°Ύμ μ μμ
κ²μνμ μν λ³ κΆν(μ½κΈ°/μ°κΈ°/λκΈ)μ μμ ν©λλ€.
PUT /api/boards/:_id/permission/:type
κΆν : admin λλ manager (isAdManager)
νλΌλ―Έν°
νμ
μ€λͺ
_id
string
κ²μν _id
type
string
κΆν μ ν: read, write, comment
νλ
νμ
νμ
μ€λͺ
manager
boolean
X
κ΄λ¦¬μ κΆν
teacher
boolean
X
κ΅μ¬ κΆν
student
boolean
X
νμ κΆν
{
"manager" : true ,
"teacher" : true ,
"student" : false
}
{
"board" : {
"_id" : " 507f1f77bcf86cd799439023" ,
"permissionWrite" : {
"manager" : true ,
"teacher" : true ,
"student" : false ,
"exceptions" : []
}
}
}
μν μ½λ
λ©μμ§
μ€λͺ
400
Invalid permission type
μλͺ»λ κΆν μ ν (read, write, comment μ΄μΈμ κ°)
404
__NOT_FOUND(board)
κ²μνμ μ°Ύμ μ μμ
κ²μν κΆν μμΈ μΆκ°
νΉμ μ¬μ©μμ λν κΆν μμΈλ₯Ό μΆκ°ν©λλ€. μν κΈ°λ° κΆνκ³Ό λ³λλ‘ κ°λ³ μ¬μ©μλ₯Ό νμ©νκ±°λ μ°¨λ¨ν μ μμ΅λλ€. μ΄λ―Έ λ±λ‘λ μ¬μ©μμ κ²½μ° isAllowed κ°μ΄ μ
λ°μ΄νΈλ©λλ€.
POST /api/boards/:_id/permission/:type/exceptions
κΆν : admin λλ manager (isAdManager)
νλΌλ―Έν°
νμ
μ€λͺ
_id
string
κ²μν _id
type
string
κΆν μ ν: read, write, comment
νλ
νμ
νμ
μ€λͺ
user
string
O
μ¬μ©μ _id
userId
string
O
μ¬μ©μ λ‘κ·ΈμΈ ID
userName
string
O
μ¬μ©μ μ΄λ¦
isAllowed
boolean
O
νμ© μ¬λΆ (true: μμΈ νμ©, false: μμΈ μ°¨λ¨)
{
"user" : " 507f1f77bcf86cd799439044" ,
"userId" : " student01" ,
"userName" : " νκΈΈλ" ,
"isAllowed" : true
}
{
"board" : {
"_id" : " 507f1f77bcf86cd799439023" ,
"permissionWrite" : {
"manager" : true ,
"teacher" : true ,
"student" : false ,
"exceptions" : [
{
"user" : " 507f1f77bcf86cd799439044" ,
"userId" : " student01" ,
"userName" : " νκΈΈλ" ,
"isAllowed" : true
}
]
}
}
}
μν μ½λ
λ©μμ§
μ€λͺ
400
FIELD_REQUIRED({νλλͺ
})
νμ νλ λλ½ (user, userId, userName, isAllowed)
400
Invalid permission type
μλͺ»λ κΆν μ ν
404
__NOT_FOUND(board)
κ²μνμ μ°Ύμ μ μμ
κ²μν κΆν μμΈ μμ
νΉμ μ¬μ©μμ λν κΆν μμΈλ₯Ό μμ ν©λλ€.
DELETE /api/boards/:_id/permission/:type/exceptions?userId={userId}
κΆν : admin λλ manager (isAdManager)
νλΌλ―Έν°
νμ
μ€λͺ
_id
string
κ²μν _id
type
string
κΆν μ ν: read, write, comment
νλΌλ―Έν°
νμ
νμ
μ€λͺ
userId
string
O
μμ ν μ¬μ©μμ λ‘κ·ΈμΈ ID
{
"board" : {
"_id" : " 507f1f77bcf86cd799439023" ,
"permissionWrite" : {
"manager" : true ,
"teacher" : true ,
"student" : false ,
"exceptions" : []
}
}
}
μν μ½λ
λ©μμ§
μ€λͺ
400
FIELD_REQUIRED(userId)
userId νλΌλ―Έν° λλ½
400
Invalid permission type
μλͺ»λ κΆν μ ν
404
__NOT_FOUND(board)
κ²μνμ μ°Ύμ μ μμ
κ²μνμ λΉνμ±νν©λλ€ (μννΈ μμ ). κΈ°λ³Έ κ²μν(곡μ§μ¬ν)μ μμ ν μ μμ΅λλ€.
κΆν : admin λλ manager (isAdManager)
νλΌλ―Έν°
νμ
μ€λͺ
_id
string
κ²μν _id
μν μ½λ
λ©μμ§
μ€λͺ
400
κΈ°λ³Έ κ²μνμ μμ ν μ μμ΅λλ€.
κΈ°λ³Έ κ²μν μμ μλ
404
__NOT_FOUND(board)
κ²μνμ μ°Ύμ μ μμ
μ°Έκ³ : μμ λ κ²μνμ isActive=falseλ‘ μ€μ λλ©°, κ²μν λͺ©λ‘ μ‘°ν μ λ°νλμ§ μμ΅λλ€.
κ²μκΈμ μμ±ν©λλ€. μμ± μ λμ μ¬μ©μμκ² μλμΌλ‘ μλ¦Όμ΄ λ°μ‘λ©λλ€ (μ΅λ 100λͺ
).
κΆν : λ‘κ·ΈμΈ (isLoggedIn) + κ²μν μ°κΈ° κΆν
νλ
νμ
νμ
μ€λͺ
board
string
O
κ²μν _id
title
string
O
μ λͺ©
content
string
O
λ΄μ© (Markdown)
category
string
X
μΉ΄ν
κ³ λ¦¬
attachments
object[]
X
첨λΆνμΌ λͺ©λ‘
attachments[].url
string
X
νμΌ URL
attachments[].fileName
string
X
νμΌλͺ
attachments[].fileSize
number
X
νμΌ ν¬κΈ° (bytes)
attachments[].mimeType
string
X
MIME νμ
attachments[].key
string
X
S3 ν€
targetAudience
object
X
λμ μ§μ (κΈ°λ³Έ: { type: "all" })
targetAudience.type
string
X
all, manager, teacher, student, custom
targetAudience.users
object[]
X
customμΈ κ²½μ° μ¬μ©μ λͺ©λ‘
targetAudience.grade
number
X
νλ
μ§μ (μ΅μ
)
{
"board" : " 507f1f77bcf86cd799439022" ,
"title" : " 3μ νκ΅ νμ¬ μλ΄" ,
"content" : " ## 3μ νκ΅ νμ¬\n\n λ€μκ³Ό κ°μ΄ νμ¬κ° μ§νλ©λλ€.\n\n - 3/5 μ
νμ\n - 3/15 νλΆλͺ¨ μλ΄\n - 3/20 체μ‘λν" ,
"category" : " νμ¬" ,
"attachments" : [
{
"url" : " https://s3.example.com/files/schedule.pdf" ,
"fileName" : " 3μ_νμ¬μΌμ .pdf" ,
"fileSize" : 102400 ,
"mimeType" : " application/pdf" ,
"key" : " files/schedule.pdf"
}
],
"targetAudience" : {
"type" : " all"
}
}
{
"post" : {
"_id" : " 507f1f77bcf86cd799439055" ,
"board" : " 507f1f77bcf86cd799439022" ,
"author" : " 507f1f77bcf86cd799439033" ,
"authorId" : " admin01" ,
"authorName" : " κ΄λ¦¬μ" ,
"authorProfile" : " https://s3.example.com/profiles/admin01.jpg" ,
"title" : " 3μ νκ΅ νμ¬ μλ΄" ,
"content" : " ## 3μ νκ΅ νμ¬\n\n λ€μκ³Ό κ°μ΄ νμ¬κ° μ§νλ©λλ€.\n\n - 3/5 μ
νμ\n - 3/15 νλΆλͺ¨ μλ΄\n - 3/20 체μ‘λν" ,
"category" : " νμ¬" ,
"isPinned" : false ,
"isActive" : true ,
"viewCount" : 0 ,
"attachments" : [
{
"url" : " https://s3.example.com/files/schedule.pdf" ,
"fileName" : " 3μ_νμ¬μΌμ .pdf" ,
"fileSize" : 102400 ,
"mimeType" : " application/pdf" ,
"key" : " files/schedule.pdf"
}
],
"targetAudience" : {
"type" : " all"
},
"createdAt" : " 2024-03-01T09:00:00.000Z" ,
"updatedAt" : " 2024-03-01T09:00:00.000Z"
}
}
μν μ½λ
λ©μμ§
μ€λͺ
400
FIELD_REQUIRED({νλλͺ
})
νμ νλ λλ½ (board, title, content)
403
PERMISSION_DENIED
μ°κΈ° κΆν μμ
404
__NOT_FOUND(board)
κ²μνμ μ°Ύμ μ μμ
κ²μκΈμ λ¨μΌ λλ λͺ©λ‘μΌλ‘ μ‘°νν©λλ€. λ¨μΌ μ‘°ν μ μ‘°νμκ° 1 μ¦κ°ν©λλ€.
κΆν : λ‘κ·ΈμΈ (isLoggedIn) + μ½κΈ° κΆν + targetAudience νμΈ
νλΌλ―Έν°
νμ
μ€λͺ
_id
string
κ²μκΈ _id
{
"post" : {
"_id" : " 507f1f77bcf86cd799439055" ,
"board" : " 507f1f77bcf86cd799439022" ,
"author" : " 507f1f77bcf86cd799439033" ,
"authorId" : " admin01" ,
"authorName" : " κ΄λ¦¬μ" ,
"authorProfile" : " https://s3.example.com/profiles/admin01.jpg" ,
"title" : " 3μ νκ΅ νμ¬ μλ΄" ,
"content" : " ## 3μ νκ΅ νμ¬\n\n λ€μκ³Ό κ°μ΄ νμ¬κ° μ§νλ©λλ€." ,
"category" : " νμ¬" ,
"isPinned" : false ,
"isActive" : true ,
"viewCount" : 16 ,
"attachments" : [],
"targetAudience" : { "type" : " all" },
"createdAt" : " 2024-03-01T09:00:00.000Z" ,
"updatedAt" : " 2024-03-01T09:00:00.000Z"
},
"board" : {
"_id" : " 507f1f77bcf86cd799439022" ,
"name" : " 곡μ§μ¬ν" ,
"slug" : " announcements"
}
}
κ²μκΈ λͺ©λ‘μ 컀μ κΈ°λ° νμ΄μ§λ€μ΄μ
μΌλ‘ μ‘°νν©λλ€. κ³ μ λ κ²μκΈμ΄ λ¨Όμ νμλκ³ , μ΄ν μ΅μ μμΌλ‘ μ λ ¬λ©λλ€.
GET /api/posts?board={board._id}&limit={limit}&before={before}
κΆν : λ‘κ·ΈμΈ (isLoggedIn) + μ½κΈ° κΆν
νλΌλ―Έν°
νμ
νμ
μ€λͺ
board
string
O
κ²μν _id
limit
number
X
νμ΄μ§ ν¬κΈ° (κΈ°λ³Έ: 20)
before
string
X
컀μ (μ΄μ νμ΄μ§μ λ§μ§λ§ κ²μκΈ createdAt, ISO 8601)
{
"posts" : [
{
"_id" : " 507f1f77bcf86cd799439066" ,
"board" : " 507f1f77bcf86cd799439022" ,
"authorId" : " admin01" ,
"authorName" : " κ΄λ¦¬μ" ,
"title" : " [μ€μ] νμ¬μΌμ λ³κ²½ μλ΄" ,
"category" : " 곡μ§" ,
"isPinned" : true ,
"isActive" : true ,
"viewCount" : 120 ,
"targetAudience" : { "type" : " all" },
"createdAt" : " 2024-02-20T09:00:00.000Z"
},
{
"_id" : " 507f1f77bcf86cd799439055" ,
"board" : " 507f1f77bcf86cd799439022" ,
"authorId" : " teacher01" ,
"authorName" : " κΉμ μ" ,
"title" : " 3μ νκ΅ νμ¬ μλ΄" ,
"category" : " νμ¬" ,
"isPinned" : false ,
"isActive" : true ,
"viewCount" : 15 ,
"targetAudience" : { "type" : " all" },
"createdAt" : " 2024-03-01T09:00:00.000Z"
}
],
"board" : {
"_id" : " 507f1f77bcf86cd799439022" ,
"name" : " 곡μ§μ¬ν"
}
}
μ°Έκ³ : λͺ©λ‘ μ‘°ν μ content νλλ μ μΈλ©λλ€. κΈ°λ³Έ κ²μν(곡μ§μ¬ν)μΈ κ²½μ° κΈ°μ‘΄ μλ¦Ό(Notification)λ ν¨κ» λ°νλ©λλ€.
μν μ½λ
λ©μμ§
μ€λͺ
400
FIELD_REQUIRED(board)
λͺ©λ‘ μ‘°ν μ board νλΌλ―Έν° λλ½
403
PERMISSION_DENIED
μ½κΈ° κΆν μμ λλ targetAudience λμ μλ
404
__NOT_FOUND(post)
κ²μκΈμ μ°Ύμ μ μμ
404
__NOT_FOUND(board)
κ²μνμ μ°Ύμ μ μμ
κ²μκΈμ μμ ν©λλ€. μμ±μ λ³ΈμΈ λλ κ΄λ¦¬μ(admin, manager)λ§ μμ ν μ μμ΅λλ€.
κΆν : λ‘κ·ΈμΈ (isLoggedIn), μμ±μ λλ κ΄λ¦¬μ
νλΌλ―Έν°
νμ
μ€λͺ
_id
string
κ²μκΈ _id
νλ
νμ
νμ
μ€λͺ
title
string
X
μ λͺ©
content
string
X
λ΄μ© (Markdown)
category
string
X
μΉ΄ν
κ³ λ¦¬
attachments
object[]
X
첨λΆνμΌ λͺ©λ‘
targetAudience
object
X
λμ μ§μ
{
"title" : " 3μ νκ΅ νμ¬ μλ΄ (μμ )" ,
"content" : " ## 3μ νκ΅ νμ¬ (μμ )\n\n μΌμ μ΄ λ³κ²½λμμ΅λλ€." ,
"category" : " νμ¬"
}
{
"post" : {
"_id" : " 507f1f77bcf86cd799439055" ,
"title" : " 3μ νκ΅ νμ¬ μλ΄ (μμ )" ,
"content" : " ## 3μ νκ΅ νμ¬ (μμ )\n\n μΌμ μ΄ λ³κ²½λμμ΅λλ€." ,
"category" : " νμ¬" ,
"updatedAt" : " 2024-03-02T10:00:00.000Z"
}
}
μν μ½λ
λ©μμ§
μ€λͺ
403
PERMISSION_DENIED
μμ±μλ μλκ³ κ΄λ¦¬μλ μλ
404
__NOT_FOUND(post)
κ²μκΈμ μ°Ύμ μ μμ
κ²μκΈμ μλ¨μ κ³ μ νκ±°λ ν΄μ ν©λλ€. κ³ μ λ κ²μκΈμ λͺ©λ‘ μ‘°ν μ νμ λ¨Όμ νμλ©λλ€.
κΆν : admin λλ manager (isAdManager)
νλΌλ―Έν°
νμ
μ€λͺ
_id
string
κ²μκΈ _id
νλ
νμ
νμ
μ€λͺ
isPinned
boolean
O
true(κ³ μ ) / false(ν΄μ )
{
"post" : {
"_id" : " 507f1f77bcf86cd799439055" ,
"isPinned" : true ,
"updatedAt" : " 2024-03-02T10:00:00.000Z"
}
}
μν μ½λ
λ©μμ§
μ€λͺ
400
FIELD_REQUIRED(isPinned)
isPinned νλ λλ½
404
__NOT_FOUND(post)
κ²μκΈμ μ°Ύμ μ μμ
κ²μκΈμ λΉνμ±νν©λλ€ (μννΈ μμ ). μμ±μ λ³ΈμΈ λλ κ΄λ¦¬μ(admin, manager)λ§ μμ ν μ μμ΅λλ€. μμ μ κ²μνμ postCountκ° κ°μν©λλ€.
κΆν : λ‘κ·ΈμΈ (isLoggedIn), μμ±μ λλ κ΄λ¦¬μ
νλΌλ―Έν°
νμ
μ€λͺ
_id
string
κ²μκΈ _id
μν μ½λ
λ©μμ§
μ€λͺ
403
PERMISSION_DENIED
μμ±μλ μλκ³ κ΄λ¦¬μλ μλ
404
__NOT_FOUND(post)
κ²μκΈμ μ°Ύμ μ μμ
μ°Έκ³ : λ κ±°μ μλ¦Ό(Notification)μΈ κ²½μ°μλ μννΈ μμ κ° μλ μ€μ μμ (deleteOne)κ° μνλ©λλ€.
κ²μκΈμ λκΈμ μμ±ν©λλ€. parentCommentλ₯Ό μ§μ νλ©΄ λλκΈ(λ΅κΈ)λ‘ μμ±λ©λλ€. λΆλͺ¨ λκΈμ κ°μ κ²μκΈμ μν΄μΌ ν©λλ€.
κΆν : λ‘κ·ΈμΈ (isLoggedIn) + κ²μν λκΈ κΆν
νλ
νμ
νμ
μ€λͺ
post
string
O
κ²μκΈ _id
content
string
O
λκΈ λ΄μ©
parentComment
string
X
λΆλͺ¨ λκΈ _id (λλκΈμΈ κ²½μ°)
{
"post" : " 507f1f77bcf86cd799439055" ,
"content" : " νμ¬ μΌμ νμΈνμ΅λλ€. κ°μ¬ν©λλ€!"
}
{
"post" : " 507f1f77bcf86cd799439055" ,
"content" : " μ λ μ°Έμνκ² μ΅λλ€." ,
"parentComment" : " 507f1f77bcf86cd799439077"
}
{
"comment" : {
"_id" : " 507f1f77bcf86cd799439077" ,
"post" : " 507f1f77bcf86cd799439055" ,
"author" : " 507f1f77bcf86cd799439044" ,
"authorId" : " teacher01" ,
"authorName" : " κΉμ μ" ,
"authorProfile" : " https://s3.example.com/profiles/teacher01.jpg" ,
"content" : " νμ¬ μΌμ νμΈνμ΅λλ€. κ°μ¬ν©λλ€!" ,
"parentComment" : null ,
"isActive" : true ,
"createdAt" : " 2024-03-01T10:30:00.000Z" ,
"updatedAt" : " 2024-03-01T10:30:00.000Z"
}
}
μν μ½λ
λ©μμ§
μ€λͺ
400
FIELD_REQUIRED({νλλͺ
})
νμ νλ λλ½ (post, content)
400
Parent comment is not in the same post
λΆλͺ¨ λκΈμ΄ λ€λ₯Έ κ²μκΈμ μν¨
403
PERMISSION_DENIED
λκΈ μμ± κΆν μμ
404
__NOT_FOUND(post)
κ²μκΈμ μ°Ύμ μ μμ
404
__NOT_FOUND(board)
κ²μνμ μ°Ύμ μ μμ
404
__NOT_FOUND(parentComment)
λΆλͺ¨ λκΈμ μ°Ύμ μ μμ
νΉμ κ²μκΈμ λκΈ λͺ©λ‘μ μ‘°νν©λλ€. μμ± μκ° μ€λ¦μ°¨μ(μ€λλ μ)μΌλ‘ μ λ ¬λ©λλ€.
GET /api/comments?post={post._id}
κΆν : λ‘κ·ΈμΈ (isLoggedIn) + κ²μν μ½κΈ° κΆν
νλΌλ―Έν°
νμ
νμ
μ€λͺ
post
string
O
κ²μκΈ _id
{
"comments" : [
{
"_id" : " 507f1f77bcf86cd799439077" ,
"post" : " 507f1f77bcf86cd799439055" ,
"author" : " 507f1f77bcf86cd799439044" ,
"authorId" : " teacher01" ,
"authorName" : " κΉμ μ" ,
"authorProfile" : " https://s3.example.com/profiles/teacher01.jpg" ,
"content" : " νμ¬ μΌμ νμΈνμ΅λλ€. κ°μ¬ν©λλ€!" ,
"parentComment" : null ,
"isActive" : true ,
"createdAt" : " 2024-03-01T10:30:00.000Z" ,
"updatedAt" : " 2024-03-01T10:30:00.000Z"
},
{
"_id" : " 507f1f77bcf86cd799439078" ,
"post" : " 507f1f77bcf86cd799439055" ,
"author" : " 507f1f77bcf86cd799439045" ,
"authorId" : " student01" ,
"authorName" : " νκΈΈλ" ,
"content" : " μ λ μ°Έμνκ² μ΅λλ€." ,
"parentComment" : " 507f1f77bcf86cd799439077" ,
"isActive" : true ,
"createdAt" : " 2024-03-01T11:00:00.000Z" ,
"updatedAt" : " 2024-03-01T11:00:00.000Z"
}
]
}
μν μ½λ
λ©μμ§
μ€λͺ
400
FIELD_REQUIRED(post)
post νλΌλ―Έν° λλ½
403
PERMISSION_DENIED
μ½κΈ° κΆν μμ
404
__NOT_FOUND(post)
κ²μκΈμ μ°Ύμ μ μμ
404
__NOT_FOUND(board)
κ²μνμ μ°Ύμ μ μμ
λκΈμ μμ ν©λλ€. μμ±μ λ³ΈμΈ λλ κ΄λ¦¬μ(admin, manager)λ§ μμ ν μ μμ΅λλ€.
κΆν : λ‘κ·ΈμΈ (isLoggedIn), μμ±μ λλ κ΄λ¦¬μ
νλΌλ―Έν°
νμ
μ€λͺ
_id
string
λκΈ _id
νλ
νμ
νμ
μ€λͺ
content
string
X
λκΈ λ΄μ©
{
"content" : " νμ¬ μΌμ νμΈνμ΅λλ€. μμ λ μΌμ λ°μ λΆνλ립λλ€."
}
{
"comment" : {
"_id" : " 507f1f77bcf86cd799439077" ,
"content" : " νμ¬ μΌμ νμΈνμ΅λλ€. μμ λ μΌμ λ°μ λΆνλ립λλ€." ,
"updatedAt" : " 2024-03-01T12:00:00.000Z"
}
}
μν μ½λ
λ©μμ§
μ€λͺ
403
PERMISSION_DENIED
μμ±μλ μλκ³ κ΄λ¦¬μλ μλ
404
__NOT_FOUND(comment)
λκΈμ μ°Ύμ μ μμ
λκΈμ λΉνμ±νν©λλ€ (μννΈ μμ ). μμ±μ λ³ΈμΈ λλ κ΄λ¦¬μ(admin, manager)λ§ μμ ν μ μμ΅λλ€.
DELETE /api/comments/:_id
κΆν : λ‘κ·ΈμΈ (isLoggedIn), μμ±μ λλ κ΄λ¦¬μ
νλΌλ―Έν°
νμ
μ€λͺ
_id
string
λκΈ _id
μν μ½λ
λ©μμ§
μ€λͺ
403
PERMISSION_DENIED
μμ±μλ μλκ³ κ΄λ¦¬μλ μλ
404
__NOT_FOUND(comment)
λκΈμ μ°Ύμ μ μμ
κ²μνμ μν κΈ°λ° κΆν μμ€ν
μ μ¬μ©ν©λλ€. κ° κ²μνμ λν΄ μ½κΈ°(read), μ°κΈ°(write), λκΈ(comment) κΆνμ μν λ³λ‘ μ€μ ν μ μμ΅λλ€.
μν
μ€λͺ
manager
κ΄λ¦¬μ (νκ΅ λ§€λμ )
teacher
κ΅μ¬
student
νμ
admin κΆνμ κ°μ§ μ¬μ©μλ λͺ¨λ κ²μνμ μ κ·Όν μ μμ΅λλ€.
exceptions λ°°μ΄μ ν΅ν΄ νΉμ μ¬μ©μμ λν μμΈλ₯Ό μ€μ ν μ μμ΅λλ€ (isAllowed: trueλ μμΈ νμ©, falseλ μμΈ μ°¨λ¨).
targetAudience (λμ μ§μ )
κ²μκΈ μμ± μ μ΄λ λμμ μ§μ ν μ μμ΅λλ€.
νμ
μ€λͺ
all
μ 체 κ³΅κ° (κΈ°λ³Έκ°)
manager
κ΄λ¦¬μλ§
teacher
κ΅μ¬λ§
student
νμλ§
custom
νΉμ μ¬μ©μ μ§μ (users λ°°μ΄ νμ)
λͺ¨λ μμ μμ
μ μννΈ μμ (isActive=false)λ‘ μ²λ¦¬λ©λλ€. μμ λ λ°μ΄ν°λ λͺ©λ‘ μ‘°νμμ μ μΈλμ§λ§ λ°μ΄ν°λ² μ΄μ€μλ μ μ§λ©λλ€.
κΈ°λ³Έ κ²μν (곡μ§μ¬ν)
νκ΅λ³λ‘ νλμ κΈ°λ³Έ κ²μν(곡μ§μ¬ν)μ΄ μλ μμ±λ©λλ€. κΈ°λ³Έ κ²μνμ λ€μ νΉμ±μ κ°μ΅λλ€:
isDefault: true
μ΄λ¦ λ³κ²½ λΆκ°
μμ λΆκ°
κΈ°μ‘΄ μλ¦Ό(Notification)λ κ²μκΈλ‘ ν¨κ» νμ (λ κ±°μ μ§μ)
컀μ κΈ°λ° νμ΄μ§λ€μ΄μ
κ²μκΈ λͺ©λ‘μ 컀μ κΈ°λ° νμ΄μ§λ€μ΄μ
μ μ¬μ©ν©λλ€. before νλΌλ―Έν°μ μ΄μ νμ΄μ§ λ§μ§λ§ κ²μκΈμ createdAt κ°μ μ λ¬νλ©΄ ν΄λΉ μμ μ΄μ μ κ²μκΈμ μ‘°νν©λλ€.
νλ‘ νΈμλ API ν¨μ (useAPIv2)
ν¨μλͺ
λ©μλ
κ²½λ‘
μ€λͺ
CBoard
POST
/api/boards
κ²μν μμ±
RBoards
GET
/api/boards?school=
κ²μν λͺ©λ‘ μ‘°ν
RBoard
GET
/api/boards/:_id
κ²μν λ¨μΌ μ‘°ν
UBoard
PUT
/api/boards/:_id
κ²μν μμ
UBoardPermission
PUT
/api/boards/:_id/permission/:type
κ²μν κΆν μμ
CBoardPermissionException
POST
/api/boards/:_id/permission/:type/exceptions
κΆν μμΈ μΆκ°
DBoardPermissionException
DELETE
/api/boards/:_id/permission/:type/exceptions
κΆν μμΈ μμ
DBoard
DELETE
/api/boards/:_id
κ²μν μμ
ν¨μλͺ
λ©μλ
κ²½λ‘
μ€λͺ
CPost
POST
/api/posts
κ²μκΈ μμ±
RPosts
GET
/api/posts?board=&limit=&before=
κ²μκΈ λͺ©λ‘ μ‘°ν
RPost
GET
/api/posts/:_id
κ²μκΈ λ¨μΌ μ‘°ν
UPost
PUT
/api/posts/:_id
κ²μκΈ μμ
UPostPin
PUT
/api/posts/:_id/pin
κ²μκΈ κ³ μ /ν΄μ
DPost
DELETE
/api/posts/:_id
κ²μκΈ μμ
CommentAPI
ν¨μλͺ
λ©μλ
κ²½λ‘
μ€λͺ
CComment
POST
/api/comments
λκΈ μμ±
RComments
GET
/api/comments?post=
λκΈ λͺ©λ‘ μ‘°ν
UComment
PUT
/api/comments/:_id
λκΈ μμ
DComment
DELETE
/api/comments/:_id
λκΈ μμ