|
|
|
@ -10,7 +10,7 @@ module.exports = (connection) => connection.model('series', new Schema({ |
|
|
|
|
user: String, //uid
|
|
|
|
|
timestamp: String, //Date.getTime(),
|
|
|
|
|
action: String |
|
|
|
|
}], default: []}, |
|
|
|
|
}], default: () => ([])}, |
|
|
|
|
completed: {type: Boolean, default: false}, //SUBMISSION completed
|
|
|
|
|
viewable: {type: Boolean, default: false}, // exists solely as completion override. WILL NOT make a completed series invisible if false
|
|
|
|
|
approved: {type: Schema.Types.Mixed, default: false}, //boolean or {approved: Boolean, by: <uid>}
|
|
|
|
@ -19,13 +19,13 @@ module.exports = (connection) => connection.model('series', new Schema({ |
|
|
|
|
reviewFlags: {type: [{ |
|
|
|
|
by: String, |
|
|
|
|
reason: String, |
|
|
|
|
}], default: []} // notes left by an admin or curator about work that needs to be done on a series for it to be approved
|
|
|
|
|
}], default: () => ([])} // notes left by an admin or curator about work that needs to be done on a series for it to be approved
|
|
|
|
|
}, //!REQ
|
|
|
|
|
|
|
|
|
|
name: {type: String, required: true, maxLength: 150}, //!REQ
|
|
|
|
|
romaji: {type: String, required: true, maxLength: 150}, //!REQ
|
|
|
|
|
kanji: {type: String, maxLength: 150, default: null}, |
|
|
|
|
altNames: {type: [{type: String, maxLength: 150}], default: []}, |
|
|
|
|
altNames: {type: [{type: String, maxLength: 150}], default: () => ([])}, |
|
|
|
|
|
|
|
|
|
synopsis: {type: { |
|
|
|
|
synopsis: {type: String, required: true, maxLength: 1000}, |
|
|
|
@ -33,33 +33,40 @@ module.exports = (connection) => connection.model('series', new Schema({ |
|
|
|
|
}, required: true}, //if not present, use "Synopsis not available yet" //!REQ
|
|
|
|
|
genres: {type: [{type: String, maxLength: 25}], required: true}, //!REQ
|
|
|
|
|
//TODO database for genres or cache
|
|
|
|
|
tags: {default: [], type: [{type: String, maxLength: 25}], lowercase: true}, |
|
|
|
|
tags: {default: () => ([]), type: [{type: String, maxLength: 25}]}, |
|
|
|
|
nsfw: {type: Boolean, default: false}, |
|
|
|
|
nsfwReason: {type: String, default: null}, //gore, language, nudity, strong themes
|
|
|
|
|
|
|
|
|
|
completed: {type: Boolean, default: false}, //SERIES completed
|
|
|
|
|
streamAt: {type: [{type: String, maxLength: 25}], default: []}, |
|
|
|
|
publishers: {type: [{type: String, maxLength: 50}], default: []}, |
|
|
|
|
studios: {type: [{type: String, maxLength: 50}], default: []}, |
|
|
|
|
streamAt: {type: [{type: String, maxLength: 25}], default: () => ([])}, |
|
|
|
|
publishers: {type: [{type: String, maxLength: 50}], default: () => ([])}, |
|
|
|
|
studios: {type: [{type: String, maxLength: 50}], default: () => ([])}, |
|
|
|
|
air: { |
|
|
|
|
from: {type: String, default: null}, //absence of start date means anime is confirmed but not released //TODO special handling for unstarted series
|
|
|
|
|
to: {type: String, default: null} //null indicates still airing; completed: true + non-null "to" value means series is waiting on another season
|
|
|
|
|
}, |
|
|
|
|
externalLinks: { |
|
|
|
|
type: [{ |
|
|
|
|
|
|
|
|
|
}], default: {} |
|
|
|
|
name: {type: String, maxLength: 100}, |
|
|
|
|
url: {type: String, maxLength: 300} |
|
|
|
|
}], default: () => ([]) |
|
|
|
|
}, //streaming services, other databases, etc. //TODO externalLinks
|
|
|
|
|
officialSite: {type: String, default: null}, |
|
|
|
|
videos: {type: Object, default: {}}, //OPs, EDs, trailers, etc.
|
|
|
|
|
videos: { |
|
|
|
|
type: [{ |
|
|
|
|
title: {type: String, maxLength: 100}, // Colors - Flow
|
|
|
|
|
subtitle: {type: String, maxLength: 100}, // Code Geass OP 1 (Season 1),
|
|
|
|
|
url: {type: String, maxLength: 500} // https://youtube.com/watch?v=...
|
|
|
|
|
}], default: () => ([]) |
|
|
|
|
}, //OPs, EDs, trailers, etc.
|
|
|
|
|
|
|
|
|
|
art: { |
|
|
|
|
cover: {type: [String], default: []}, //first item of any list is default item
|
|
|
|
|
icon: {type: [String], default: []}, //small 128x128 icon
|
|
|
|
|
banner: {type: [String], default: []}, |
|
|
|
|
poster: {type: [String], default: []}, //used for BGs, portrait
|
|
|
|
|
widePoster: {type: [String], default: []}, //used for desktop, client should format banners or displays at its discretion if unavailable
|
|
|
|
|
display: {type: [String], default: []}, //used for some content BGs, landscape standard desktop res.
|
|
|
|
|
cover: {type: [String], default: () => ([])}, //first item of any list is default item
|
|
|
|
|
icon: {type: [String], default: () => ([])}, //small 128x128 icon
|
|
|
|
|
banner: {type: [String], default: () => ([])}, |
|
|
|
|
poster: {type: [String], default: () => ([])}, //used for BGs, portrait
|
|
|
|
|
widePoster: {type: [String], default: () => ([])}, //used for desktop, client should format banners or displays at its discretion if unavailable
|
|
|
|
|
display: {type: [String], default: () => ([])}, //used for some content BGs, landscape standard desktop res.
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
ratings: {type: [{ |
|
|
|
@ -67,18 +74,18 @@ module.exports = (connection) => connection.model('series', new Schema({ |
|
|
|
|
rating: Number |
|
|
|
|
}], default: () => ([])}, //all ratings mapped by user
|
|
|
|
|
rating: {type: Number, default: 0}, //automatic collection of user ratings for avg.
|
|
|
|
|
watchers: {type: [String], default: []}, //people with this anime on their watching and/or watchlists
|
|
|
|
|
watchers: {type: [String], default: () => ([])}, //people with this anime on their watching and/or watchlists
|
|
|
|
|
likes: {type: Number, default: 0}, //no need to map by user here
|
|
|
|
|
reviews: {type: [{ //full review vs rating
|
|
|
|
|
user: String, |
|
|
|
|
ratings: { |
|
|
|
|
plot: Number, |
|
|
|
|
characters: Number, |
|
|
|
|
soundtrack: Number, |
|
|
|
|
animation: Number |
|
|
|
|
plot: {type: Number, min: 1, max: 5, required: true}, |
|
|
|
|
characters: {type: Number, min: 1, max: 5, required: true}, |
|
|
|
|
soundtrack: {type: Number, min: 1, max: 5, required: true}, |
|
|
|
|
animation: {type: Number, min: 1, max: 5, required: true} |
|
|
|
|
}, |
|
|
|
|
comments: {type: String, maxLength: 2000} |
|
|
|
|
}], default: [] |
|
|
|
|
}], default: () => ([]) |
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -88,7 +95,7 @@ module.exports = (connection) => connection.model('series', new Schema({ |
|
|
|
|
* Stores only IDs and barebones data, requires clients to fetch their contents |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
seasons: {type: [String], default: []}, |
|
|
|
|
characters: {type: [String], default: []}, |
|
|
|
|
related: {type: [String], default: []} //TODO this shit even necessary?
|
|
|
|
|
seasons: {type: [String], default: () => ([])}, |
|
|
|
|
characters: {type: [String], default: () => ([])}, |
|
|
|
|
related: {type: [String], default: () => ([])} //TODO this shit even necessary?
|
|
|
|
|
})); |