diff --git a/README.md b/README.md index 8f94667f9d2..15ba559e4a5 100644 --- a/README.md +++ b/README.md @@ -114,8 +114,8 @@ Project Structure | **controllers**/home.js | Controller for home page (index). | | **controllers**/user.js | Controller for user account management. | | **controllers**/challenges.js | Controller for rendering the challenges. | -| **models**/User.js | Mongoose schema and model for User. | -| **models**/Challenge.js | Mongoose schema and model for Challenge. | +| **models**/user.json | Mongoose schema and model for User. | +| **models**/challenge.json | Mongoose schema and model for Challenge. | | **public**/ | Static assets (fonts, css, js, img). | | **public**/**js**/application.js | Specify client-side JavaScript dependencies. | | **public**/**js**/main_0.0.2.js | Place your client-side JavaScript here. | diff --git a/common/models/Challenge.js b/common/models/Challenge.js deleted file mode 100644 index ae0863b6cd9..00000000000 --- a/common/models/Challenge.js +++ /dev/null @@ -1,32 +0,0 @@ -var mongoose = require('mongoose'); - -/** - * - * @type {exports.Schema} - */ - -var challengeSchema = new mongoose.Schema({ - name: { - type: String, - unique: true - }, - difficulty: String, - description: Array, - tests: Array, - challengeSeed: Array, - // 0 = html, 1 = javascript only, 2 = video, 3 = zipline, 4 = basejump - challengeType: Number, - MDNlinks: Array, - nameCn: String, - descriptionCn: Array, - nameFr: String, - descriptionFr: Array, - nameRu: String, - descriptionRu: Array, - nameEs: String, - descriptionEs: Array, - namePt: String, - descriptionPt: Array -}); - -module.exports = mongoose.model('Challenge', challengeSchema); diff --git a/common/models/Comment.js b/common/models/Comment.js deleted file mode 100644 index f3423b2cfb5..00000000000 --- a/common/models/Comment.js +++ /dev/null @@ -1,39 +0,0 @@ -var mongoose = require('mongoose'); - -var commentSchema = new mongoose.Schema({ - associatedPost: { - type: String, - required: true - }, - originalStoryLink: { - type: String, - default: '' - }, - originalStoryAuthorEmail: { - type: String, - default: '' - }, - body: { - type: String, - default: '' - }, - rank: { - type: Number, - default: -Infinity - }, - upvotes: { - type: Array, - default: [] - }, - author: {}, - comments: { - type: Array, - default: [] - }, - commentOn: { - type: Number, - default: Date.now() - } -}); - -module.exports = mongoose.model('Comment', commentSchema); diff --git a/common/models/Courseware.js b/common/models/Courseware.js deleted file mode 100644 index f6efdacbaf5..00000000000 --- a/common/models/Courseware.js +++ /dev/null @@ -1,21 +0,0 @@ -var mongoose = require('mongoose'); - -/** - * - * @type {exports.Schema} - */ - -var coursewareSchema = new mongoose.Schema({ - name: { - type: String, - unique: true - }, - difficulty: String, - description: Array, - tests: Array, - challengeSeed: Array, - // 0 = html, 1 = javascript only, 2 = video, 3 = zipline, 4 = basejump - challengeType: Number -}); - -module.exports = mongoose.model('Courseware', coursewareSchema); diff --git a/common/models/FieldGuide.js b/common/models/FieldGuide.js deleted file mode 100644 index ea1ad63e9c8..00000000000 --- a/common/models/FieldGuide.js +++ /dev/null @@ -1,18 +0,0 @@ -var mongoose = require('mongoose'); - -var fieldGuideSchema = new mongoose.Schema({ - name: { - type: String, - unique: false - }, - dashedName: { - type: String, - unique: false - }, - description: { - type: Array, - unique: false - } -}); - -module.exports = mongoose.model('FieldGuide', fieldGuideSchema); diff --git a/common/models/Job.js b/common/models/Job.js deleted file mode 100644 index a6b0d7fb049..00000000000 --- a/common/models/Job.js +++ /dev/null @@ -1,16 +0,0 @@ -var mongoose = require('mongoose'); - -/** - * - * @type {exports.Schema} - */ - -var jobSchema = new mongoose.Schema({ - position: String, - company: String, - logoUrl: String, - postingUrl: String, - copy: Array -}); - -module.exports = mongoose.model('Job', jobSchema); diff --git a/common/models/Nonprofit.js b/common/models/Nonprofit.js deleted file mode 100644 index 12e350a6d46..00000000000 --- a/common/models/Nonprofit.js +++ /dev/null @@ -1,27 +0,0 @@ -var mongoose = require('mongoose'); - -/** - * - * @type {exports.Schema} - */ - -var nonprofitSchema = new mongoose.Schema({ - name: String, - requestedDeliverables: Array, - whatDoesNonprofitDo: String, - websiteLink: String, - stakeholderName: String, - stakeholderEmail: String, - endUser: String, - approvedDeliverables: Array, - projectDescription: String, - logoUrl: String, - imageUrl: String, - estimatedHours: 0, - interestedCampers: [], - confirmedCampers: [], - // "confirmed", "started", "completed", "aborted" - currentStatus: String -}); - -module.exports = mongoose.model('Nonprofit', nonprofitSchema); diff --git a/common/models/Story.js b/common/models/Story.js deleted file mode 100644 index 1c9e5128488..00000000000 --- a/common/models/Story.js +++ /dev/null @@ -1,52 +0,0 @@ -var mongoose = require('mongoose'); - -var storySchema = new mongoose.Schema({ - headline: { - type: String, - unique: false - }, - timePosted: { - type: Number, - default: 0 - }, - link: { - type: String, - unique: false - }, - metaDescription: { - type: String, - default: '', - unique: false - }, - description: { - type: String, - unique: false - }, - originalStoryAuthorEmail: { - type: String, - default: '' - }, - rank: { - type: Number, - default: -Infinity - }, - upVotes: { - type: Array, - default: [] - }, - author: {}, - comments: { - type: Array, - default: [] - }, - image: { - type: String, - default: '' - }, - storyLink: { - type: String, - default: '' - } -}); - -module.exports = mongoose.model('Story', storySchema); diff --git a/common/models/User.js b/common/models/User.js deleted file mode 100644 index 6ff0b8b5464..00000000000 --- a/common/models/User.js +++ /dev/null @@ -1,204 +0,0 @@ -var bcrypt = require('bcrypt-nodejs'); -var mongoose = require('mongoose'); -require('mongoose-long')(mongoose); - -var Long = mongoose.Types.Long; -var userSchema = new mongoose.Schema({ - email: { - type: String, - lowercase: true, - trim: true, - sparse: true - }, - password: String, - facebook: String, - twitter: String, - google: String, - github: String, - linkedin: String, - tokens: Array, - progressTimestamps: { - type: Array, - default: [] - }, - profile: { - username: { - type: String, - sparse: true, - lowercase: true, - trim: true - }, - bio: { - type: String, - default: '' - }, - name: { - type: String, - default: '' - }, - gender: { - type: String, - default: '' - }, - location: { - type: String, - default: '' - }, - picture: { - type: String, - default: '' - }, - linkedinProfile: { - type: String, - default: '' - }, - githubProfile: { - type: String, - default: '' - }, - codepenProfile: { - type: String, - default: '' - }, - twitterHandle: { - type: String, - default: '' - }, - facebookProfile: { - type: String, - default: '' - } - }, - portfolio: { - website1Link: { - type: String, - default: '' - }, - website1Title: { - type: String, - default: '' - }, - website1Image: { - type: String, - default: '' - }, - website2Link: { - type: String, - default: '' - }, - website2Title: { - type: String, - default: '' - }, - website2Image: { - type: String, - default: '' - }, - website3Link: { - type: String, - default: '' - }, - website3Title: { - type: String, - default: '' - }, - website3Image: { - type: String, - default: '' - } - }, - resetPasswordToken: String, - sentSlackInvite: false, - resetPasswordExpires: Date, - uncompletedBonfires: Array, - completedBonfires: [{ - _id: String, - name: String, - completedWith: String, - completedDate: Long, - solution: String - }], - uncompletedCoursewares: Array, - completedCoursewares: [{ - completedDate: { - type: Long, - default: Date.now() - }, - _id: String, - name: String, - completedWith: String, - solution: String, - githubLink: String, - verified: Boolean - }], - completedFieldGuides: [], - uncompletedFieldGuides: [], - currentStreak: { - type: Number, - default: 0 - }, - longestStreak: { - type: Number, - default: 0 - }, - needsSomeDataModeled: { type: Boolean, default: false}, - - // needsMigration has been deprecated, use needsSomeDataModeled - needsMigration: { - type: Boolean, - default: true - }, - sendMonthlyEmail: { - type: Boolean, - default: true - }, - challengesHash: {}, - currentChallenge: {}, - completedChallenges: [{ - completedDate: Long, - _id: String, - name: String, - completedWith: String, - solution: String, - githubLink: String, - verified: Boolean, - challengeType: { - type: Number, - default: 0 - } - }], - uncompletedChallenges: Array -}); - -/** - * Password hashing Mongoose middleware. - */ - -userSchema.pre('save', function(next) { - var user = this; - - if (!user.isModified('password')) { return next(); } - - bcrypt.genSalt(5, function(err, salt) { - if (err) { return next(err); } - - bcrypt.hash(user.password, salt, null, function(err, hash) { - if (err) { return next(err); } - user.password = hash; - next(); - }); - }); -}); - -/** - * Helper method for validationg user's password. - */ - -userSchema.methods.comparePassword = function(candidatePassword, cb) { - bcrypt.compare(candidatePassword, this.password, function(err, isMatch) { - if (err) { return cb(err); } - cb(null, isMatch); - }); -}; - -module.exports = mongoose.model('User', userSchema); diff --git a/common/models/challenge.json b/common/models/challenge.json new file mode 100644 index 00000000000..7a55364a024 --- /dev/null +++ b/common/models/challenge.json @@ -0,0 +1,32 @@ +{ + "name": "challenge", + "base": "PersistedModel", + "trackChanges": false, + "idInjection": true, + "properties": { + "name": { + "type": "string", + "unique": true + }, + "difficulty": "string", + "description": "array", + "tests": "array", + "challengeSeed": "array", + "challengeType": "string", + "MDNlinks": "array", + "nameCn": "string", + "descriptionCn": "array", + "nameFr": "string", + "descriptionFr": "array", + "nameRu": "string", + "descriptionRu": "array", + "nameEs": "string", + "descriptionEs": "array", + "namePt": "string", + "descriptionPt": "array" + }, + "validations": [], + "relations": {}, + "acls": [], + "methods": [] +} \ No newline at end of file diff --git a/common/models/comment.json b/common/models/comment.json new file mode 100644 index 00000000000..a0e5803fc38 --- /dev/null +++ b/common/models/comment.json @@ -0,0 +1,45 @@ +{ + "name": "comment", + "base": "PersistedModel", + "trackChanges": false, + "idInjection": true, + "properties": { + "associatedPost": { + "type": "string", + "required": true + }, + "originalStoryLink": { + "type": "string", + "default": "" + }, + "originalStoryAuthorEmail": { + "type": "string", + "default": "" + }, + "body": { + "type": "string", + "default": "" + }, + "rank": { + "type": "number", + "default": "-Infinity" + }, + "upvotes": { + "type": "array", + "default": [] + }, + "author": {}, + "comments": { + "type": "array", + "default": [] + }, + "commentOn": { + "type": "number", + "defaultFn": "now" + } + }, + "validations": [], + "relations": {}, + "acls": [], + "methods": [] +} diff --git a/common/models/field-guide.json b/common/models/field-guide.json new file mode 100644 index 00000000000..2a35b987d84 --- /dev/null +++ b/common/models/field-guide.json @@ -0,0 +1,24 @@ +{ + "name": "fieldGuide", + "base": "PersistedModel", + "trackChanges": false, + "idInjection": true, + "properties": { + "name": { + "type": "string", + "unique": true + }, + "dashedName": { + "type": "string", + "unique": false + }, + "description": { + "type": "array", + "unique": false + } + }, + "validations": [], + "relations": {}, + "acls": [], + "methods": [] +} diff --git a/common/models/job.json b/common/models/job.json new file mode 100644 index 00000000000..2932fdd8729 --- /dev/null +++ b/common/models/job.json @@ -0,0 +1,17 @@ +{ + "name": "job", + "base": "PersistedModel", + "trackChanges": false, + "idInjection": true, + "properties": { + "position": "string", + "company": "string", + "logoUrl": "string", + "postingUrl": "string", + "copy": "array" + }, + "validations": [], + "relations": {}, + "acls": [], + "methods": [] +} diff --git a/common/models/nonprofit.json b/common/models/nonprofit.json new file mode 100644 index 00000000000..cea2faeb88e --- /dev/null +++ b/common/models/nonprofit.json @@ -0,0 +1,35 @@ +{ + "name": "nonprofit", + "base": "PersistedModel", + "trackChanges": false, + "idInjection": true, + "properties": { + "name": { + "type": "string", + "unique": true + }, + "requestedDeliverables": "array", + "whatDoesNonprofitDo": "string", + "websiteLink": "string", + "stakeholderName": "string", + "stakeholderEmail": "string", + "endUser": "string", + "approvedDeliverables": "array", + "projectDescription": "string", + "logoUrl": "string", + "imageUrl": "string", + "estimatedHours": 0, + "interestedCampers": [], + "confirmedCampers": [], + "currentStatus": "string" + }, + "validations": [], + "relations": {}, + "acls": [], + "methods": [] +} + + +}); + +module.exports = mongoose.model('Nonprofit', nonprofitSchema); diff --git a/common/models/story.json b/common/models/story.json new file mode 100644 index 00000000000..1d28fea97a9 --- /dev/null +++ b/common/models/story.json @@ -0,0 +1,69 @@ +{ + "name": "bonfire", + "base": "PersistedModel", + "trackChanges": false, + "idInjection": true, + "properties": { + "name": { + "type": "string", + "unique": true + }, + "headline": { + "type": "string", + "unique": false + }, + "timePosted": { + "type": "number", + "default": 0 + }, + "link": { + "type": "string", + "unique": false + }, + "metaDescription": { + "type": "string", + "default": "", + "unique": false + }, + "description": { + "type": "string", + "unique": false + }, + "originalStoryAuthorEmail": { + "type": "string", + "default": "" + }, + "rank": { + "type": "number", + "default": "-Infinity" + }, + "upVotes": { + "type": "array", + "default": [] + }, + "author": {}, + "comments": { + "type": "array", + "default": [] + }, + "image": { + "type": "string", + "default": "" + }, + "storyLink": { + "type": "string", + "default": "" + } + "difficulty": "string", + "description": "array", + "tests": "array", + "challengeSeed": "array", + "MDNlinks": { + "type": "array" + } + }, + "validations": [], + "relations": {}, + "acls": [], + "methods": [] +} diff --git a/common/models/user.json b/common/models/user.json new file mode 100644 index 00000000000..5bdab4a1b6b --- /dev/null +++ b/common/models/user.json @@ -0,0 +1,175 @@ +{ + "name": "bonfire", + "base": "PersistedModel", + "trackChanges": false, + "idInjection": true, + "properties": { + "email": { + "type": "string", + "lowercase": true, + "trim": true, + "sparse": true + }, + "password": "string", + "facebook": "string", + "twitter": "string", + "google": "string", + "github": "string", + "linkedin": "string", + "tokens": "array", + "progressTimestamps": { + "type": "array", + "default": [] + }, + "profile": { + "username": { + "type": "string", + "sparse": true, + "lowercase": true, + "trim": true + }, + "bio": { + "type": "string", + "default": "" + }, + "name": { + "type": "string", + "default": "" + }, + "gender": { + "type": "string", + "default": "" + }, + "location": { + "type": "string", + "default": "" + }, + "picture": { + "type": "string", + "default": "" + }, + "linkedinProfile": { + "type": "string", + "default": "" + }, + "githubProfile": { + "type": "string", + "default": "" + }, + "codepenProfile": { + "type": "string", + "default": "" + }, + "twitterHandle": { + "type": "string", + "default": "" + }, + "facebookProfile": { + "type": "string", + "default": "" + } + }, + "portfolio": { + "website1Link": { + "type": "string", + "default": "" + }, + "website1Title": { + "type": "string", + "default": "" + }, + "website1Image": { + "type": "string", + "default": "" + }, + "website2Link": { + "type": "string", + "default": "" + }, + "website2Title": { + "type": "string", + "default": "" + }, + "website2Image": { + "type": "string", + "default": "" + }, + "website3Link": { + "type": "string", + "default": "" + }, + "website3Title": { + "type": "string", + "default": "" + }, + "website3Image": { + "type": "string", + "default": "" + } + }, + "resetPasswordToken": "string", + "sentSlackInvite": false, + "resetPasswordExpires": "string", + "uncompletedBonfires": "array", + "completedBonfires": [{ + "_id": "string", + "name": "string", + "completedWith": "string", + "completedDate": "string", + "solution": "string" + }], + "uncompletedCoursewares": "array", + "completedCoursewares": [{ + "completedDate": { + "type": "string", + "defaultFn": "now" + }, + "_id": "string", + "name": "string", + "completedWith": "string", + "solution": "string", + "githubLink": "string", + "verified": "boolean" + }], + "completedFieldGuides": [], + "uncompletedFieldGuides": [], + "currentStreak": { + "type": "number", + "default": 0 + }, + "longestStreak": { + "type": "number", + "default": 0 + }, + "needsSomeDataModeled": { "type": "boolean", "default": false}, + + "needsMigration": { + "type": "boolean", + "default": true + }, + "sendMonthlyEmail": { + "type": "boolean", + "default": true + }, + "challengesHash": {}, + "currentChallenge": {}, + "completedChallenges": [{ + "completedDate": "number", + "_id": "string", + "name": "string", + "completedWith": "string", + "solution": "string", + "githubLink": "string", + "verified": "boolean", + "challengeType": { + "type": "number", + "default": 0 + } + }], + "uncompletedChallenges": "array" + }, + "validations": [], + "relations": {}, + "acls": [], + "methods": [] +}