@ -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?
} ) ) ;