2
\$\begingroup\$

Looking for feedback on a set of templates I've just created. I'm planning on converting them to Yeoman but want to make sure they're ready for prime time before doing so. They are currently in CodeSmith Generator format.

Their main goal is to generate the guts of a MongoDB / Mongoose / ExpressJS web service from SQL Server. Unfortunately, I'm new to MEAN Stack, so I'm not 100% confident they utilize best practices.

The actual templates are on GitHub at: Templates / Sample Output

Four main types of files are generated:

Routes Index

/*jslint node: true */
/**
* Generated by Fred Lackey <[email protected]> on 2/25/2015 1:36:56 PM
* Copyright 2015 Fred Lackey
* Direct questions to the author: Fred Lackey <[email protected]>
*/

'use strict';

var express = require('express');

var apiRouter = express.Router();

// ======================================
// Default (No Schema) (2 tables) - BEGIN
// ======================================

var bogusCodeRouter = require('./bogus-code.routes');
apiRouter.use('/bogus-code', bogusCodeRouter);

var bogusIdentifierRouter = require('./bogus-identifier.routes');
apiRouter.use('/bogus-identifier', bogusIdentifierRouter);

// ======================================
// Default (No Schema) (2 tables) - END
// ======================================

// ================================
// Communications (1 table) - BEGIN
// ================================

var messageRouter = require('./communications/message.routes');
apiRouter.use('/message', messageRouter);

// ================================
// Communications (1 table) - END
// ================================

// ====================================
// Member Management (3 tables) - BEGIN
// ====================================

var memberRouter = require('./member-management/member.routes');
apiRouter.use('/member', memberRouter);

var memberSignupRequestRouter = require('./member-management/member-signup-request.routes');
apiRouter.use('/member-signup-request', memberSignupRequestRouter);

var signupRequestRouter = require('./member-management/signup-request.routes');
apiRouter.use('/signup-request', signupRequestRouter);

// ====================================
// Member Management (3 tables) - END
// ====================================

module.exports = apiRouter;

Route

/*jslint node: true, nomen: true */
/**
* Generated by Fred Lackey <[email protected]> on 2/25/2015 1:36:56 PM
* Copyright 2015 Fred Lackey
* Direct questions to the author: Fred Lackey <[email protected]>
*/

'use strict';

var dates = require('dzutils').dates,
    moment = require('moment'),
    mongoose = require('mongoose'),
    strings = require('dzutils').strings,
    uids = require('dzutils').uuids;

var memberSchema = new mongoose.Schema({
    _id: { type: String, trim: true, uppercase: true, default: uids.newIdentifier, validate: [uids.isIdentifier, '_id (id) is not a valid identifier'], required: false },
    uid: { type: String, trim: true, uppercase: true, validate: [uids.isIdentifier, 'uid is not a valid identifier'], required: false },
    userName: { type: String, trim: true, validate: [strings.isValidString, 'userName is not a valid string'], required: false },
    passHash: { type: String, trim: true, validate: [strings.isValidString, 'passHash is not a valid string'], required: false },
    passSalt: { type: String, trim: true, validate: [strings.isValidString, 'passSalt is not a valid string'], required: false },
    _v: { type: Date, validate: [dates.isDate, '_v (auditVersionDate) is not a valid date'], required: false },
    _k: { type: Date, default: null, validate: [dates.isDateOrNull, '_k (auditDeletedDate) is not a valid date or null value'], required: true }
});

memberSchema.index({
    userName: 1,
    _k: 1
}, { unique: true });

var validateItem = function (item, callback) {
    if (!item) { return callback(new Error('No item to validate')); }
    if (typeof item._id !== 'undefined') { if (!uids.isIdentifier(item._id)) { return callback(new Error('_id (id) is not a valid String')); } else { item._id = strings.trimToNull(item._id); } }
    if (typeof item.uid !== 'undefined') { if (!uids.isIdentifier(item.uid)) { return callback(new Error('uid is not a valid String')); } else { item.uid = strings.trimToNull(item.uid); } }
    if (typeof item.userName !== 'undefined') { if (!strings.isValidString(item.userName)) { return callback(new Error('userName is not a valid String')); } else { item.userName = strings.trimToNull(item.userName); } }
    if (typeof item.passHash !== 'undefined') { if (!strings.isValidString(item.passHash)) { return callback(new Error('passHash is not a valid String')); } else { item.passHash = strings.trimToNull(item.passHash); } }
    if (typeof item.passSalt !== 'undefined') { if (!strings.isValidString(item.passSalt)) { return callback(new Error('passSalt is not a valid String')); } else { item.passSalt = strings.trimToNull(item.passSalt); } }
    if (typeof item._v !== 'undefined') { if (!strings.isDate(item._v)) { return callback(new Error('_v (auditVersionDate) is not a valid Date')); } else {  } }
    if (typeof item._k !== 'undefined') { if (!strings.isDateOrNull(item._k)) { return callback(new Error('_k (auditDeletedDate) is not a valid Date or null value')); } else {  } }
    return callback();
};
memberSchema.methods.validateItem = validateItem;

var toDto = function (item) {
    if (!item) { return null; }
    var dto = {};
    if (typeof item._id !== 'undefined') { dto.id = item._id; }
    if (typeof item.uid !== 'undefined') { dto.uid = item.uid; }
    if (typeof item.userName !== 'undefined') { dto.userName = item.userName; }
    if (typeof item.passHash !== 'undefined') { dto.passHash = item.passHash; }
    if (typeof item.passSalt !== 'undefined') { dto.passSalt = item.passSalt; }
    if (typeof item._v !== 'undefined') { dto.auditVersionDate = item._v; }
    if (typeof item._k !== 'undefined') { dto.auditDeletedDate = item._k; }
    return dto;
};
memberSchema.methods.toDto = toDto;

var toDtos = function (items) {
    if (!items || items.length < 1) { return null; }
    var i, dtos = [];
    for (i = 0; i < items.length; i += 1) {
        dtos.push(toDto(items[i]));
    }
    return dtos;
};
memberSchema.methods.toDto = toDto;

var toDtoFull = function (item) {
    if (!item) { return null; }
    var dto = {
        id: ((typeof item._id !== 'undefined') ? item._id : null),
        uid: ((typeof item.uid !== 'undefined') ? item.uid : null),
        userName: ((typeof item.userName !== 'undefined') ? item.userName : null),
        passHash: ((typeof item.passHash !== 'undefined') ? item.passHash : null),
        passSalt: ((typeof item.passSalt !== 'undefined') ? item.passSalt : null),
        auditVersionDate: ((typeof item._v !== 'undefined') ? item._v : null),
        auditDeletedDate: ((typeof item._k !== 'undefined') ? item._k : null)
    };
    return dto;
};
memberSchema.methods.toDtoFull = toDtoFull;

var toDtosFull = function (items) {
    if (!items || items.length < 1) { return null; }
    var i, dtos = [];
    for (i = 0; i < items.length; i += 1) {
        dtos.push(toDtoFull(items[i]));
    }
    return dtos;
};
memberSchema.methods.toDtosFull = toDtosFull;

var toItem = function (dto) {
    if (!dto) { return null; }
    var item = {};
    if (typeof dto.id !== 'undefined') { item._id = dto.id; }
    if (typeof dto.uid !== 'undefined') { item.uid = dto.uid; }
    if (typeof dto.userName !== 'undefined') { item.userName = dto.userName; }
    if (typeof dto.passHash !== 'undefined') { item.passHash = dto.passHash; }
    if (typeof dto.passSalt !== 'undefined') { item.passSalt = dto.passSalt; }
    if (typeof dto.auditVersionDate !== 'undefined') { item._v = dto.auditVersionDate; }
    if (typeof dto.auditDeletedDate !== 'undefined') { item._k = dto.auditDeletedDate; }
    return item;
};
memberSchema.methods.toItem = toItem;

var toItems = function toItems(dtos) {
    if (!dtos || dtos.length < 1) { return null; }
    var i, items = [];
    for (i = 0; i < dtos.length; i += 1) {
        items.push(toItem(dtos[i]));
    }
    return items;
};
memberSchema.methods.toItems = toItems;

var toItemFull = function toItemFull(dto) {
    if (!dto) { return null; }
    var item = {
        _id: ((typeof dto.id !== 'undefined') ? dto.id : null),
        uid: ((typeof dto.uid !== 'undefined') ? dto.uid : null),
        userName: ((typeof dto.userName !== 'undefined') ? dto.userName : null),
        passHash: ((typeof dto.passHash !== 'undefined') ? dto.passHash : null),
        passSalt: ((typeof dto.passSalt !== 'undefined') ? dto.passSalt : null),
        _v: ((typeof dto.auditVersionDate !== 'undefined') ? dto.auditVersionDate : null),
        _k: ((typeof dto.auditDeletedDate !== 'undefined') ? dto.auditDeletedDate : null)
    };
    return item;
};
memberSchema.methods.toItemFull = toItemFull;

var toItemsFull = function (dtos) {
    if (!dtos || dtos.length < 1) { return null; }
    var i, items = [];
    for (i = 0; i < dtos.length; i += 1) {
        items.push(toItemFull(dtos[i]));
    }
    return items;
};
memberSchema.methods.toItemsFull = toItemsFull;

var getAll = function (callback) {
    var query = { _k: null };
    mongoose.model('Member').find(query, function (err, items) {
        if (err) { return callback(err); }
        return callback(null, toDtos(items));
    });
};
memberSchema.methods.getAll = getAll;

var getById = function (id, callback) {
    var query = { _id: id, _k: null };
    validateItem(query, function (err) {
        if (err) { return callback(err); }
        mongoose.model('Member').findOne(query, function (err, item) {
            if (err) { return callback(err); }
            if (item) { return callback(null, toDto(item)); }
            return callback();
        });
    });
};
memberSchema.methods.getById = getById;

var getOneByUserName = function (userName, callback) {
    var query = {
        userName: userName,
        _k: null
    };
    validateItem(query, function (err) {
        if (err) { return callback(err); }
        mongoose.model('Member').findOne(query, function (err, item) {
            if (err) { return callback(err); }
            if (item) { return callback(null, toDto(item)); }
            return callback();
        });
    });
};
memberSchema.methods.getOneByUserName = getOneByUserName;

var createNew = function (uid, userName, passHash, passSalt, callback) {
    var data = {
        uid: uid,
        userName: userName,
        passHash: passHash,
        passSalt: passSalt,
        _v: moment().utc().toDate(),
        _k: null
    };
    validateItem(data, function (err) {
        if (err) { return callback(err); }
        var newItem = new member(data);
        newItem.save(function (err, item) {
            if (err) { return callback(err); }
            return callback(null, toDto(item));
        });
    });
};
memberSchema.methods.createNew = createNew;

var createNewOrGet = function (uid, userName, passHash, passSalt, suppressError, callback) {
    var dupErr = suppressError ? null : (new Error('Duplicate Member detected'));
    getOneByUserName(userName, function (err, existing) {
        if (err) { return callback(err); }
        if (existing) { return callback(dupErr, existing); }
        return createNew(uid, userName, passHash, passSalt, callback);
    });
};
memberSchema.methods.createNewOrGet = createNewOrGet;

var modifyMany = function (queryDto, updateDto, callback) {
    if (!updateDto) { callback(new Error('Nothing to update')); }
    updateDto.auditVersionDate = moment().utc().toDate();
    var query = toItem(queryDto),
        update = toItem(updateDto);
    validateItem(query, function (err) {
        if (err) { return callback(new Error('Invalid query: ' + err.message)); }
        validateItem(update, function (err) {
            if (err) { return callback(new Error('Invalid update: ' + err.message)); }
            return mongoose.model('Member').update(query, update, callback);
        });
    });
};
memberSchema.methods.modifyMany = modifyMany;

var modifyOne = function (queryDto, updateDto, callback) {
    if (!updateDto) { return callback(new Error('Nothing to update')); }
    updateDto.auditVersionDate = moment().utc().toDate();
    var query = toItem(queryDto),
        update = toItem(updateDto);
    validateItem(query, function (err) {
        if (err) { return callback(new Error('Invalid query: ' + err.message)); }
        validateItem(update, function (err) {
            if (err) { return callback(new Error('Invalid update: ' + err.message)); }
            mongoose.model('Member').findOneAndUpdate(query, update, function (err, item) {
                if (err) { return callback(err); }
                if (item) { return callback(null, toDto(item)); }
                return callback();
            });
        });
    });
};
memberSchema.methods.modifyOne = modifyOne;

var deleteMany = function (queryDto, callback) {
    var updateDto = { auditDeletedDate: moment().utc().toDate() };
    return modifyMany(queryDto, updateDto, callback);
};
memberSchema.methods.deleteMany = deleteMany;

var deleteOne = function (queryDto, callback) {
    var updateDto = { auditDeletedDate: moment().utc().toDate() };
    return modifyOne(queryDto, updateDto, callback);
};
memberSchema.methods.deleteOne = deleteOne;

var member = mongoose.model('Member', memberSchema);

module.exports = member;

Model Index

/*jslint node: true */
/**
* Generated by Fred Lackey <[email protected]> on 2/25/2015 1:36:56 PM
* Copyright 2015 Fred Lackey
* Direct questions to the author: Fred Lackey <[email protected]>
*/

'use strict';


// Default (No Schema) (2 tables)
var bogusCodes = require('./bogus-code.model');
var bogusIdentifiers = require('./bogus-identifier.model');

// Communications (1 table)
var messages = require('./communications/message.model');

// Member Management (3 tables)
var members = require('./member-management/member.model');
var memberSignupRequests = require('./member-management/member-signup-request.model');
var signupRequests = require('./member-management/signup-request.model');

module.exports = {
    bogusCodes: bogusCodes,
    bogusIdentifiers: bogusIdentifiers
    communications: {
        messages: messages
    },
    memberManagement: {
        members: members,
        memberSignupRequests: memberSignupRequests,
        signupRequests: signupRequests
    }
};

Model

/*jslint node: true, nomen: true */
/**
* Generated by Fred Lackey <[email protected]> on 2/25/2015 1:36:56 PM
* Copyright 2015 Fred Lackey
* Direct questions to the author: Fred Lackey <[email protected]>
*/

'use strict';

var dates = require('dzutils').dates,
    moment = require('moment'),
    mongoose = require('mongoose'),
    strings = require('dzutils').strings,
    uids = require('dzutils').uuids;

var memberSchema = new mongoose.Schema({
    _id: { type: String, trim: true, uppercase: true, default: uids.newIdentifier, validate: [uids.isIdentifier, '_id (id) is not a valid identifier'], required: false },
    uid: { type: String, trim: true, uppercase: true, validate: [uids.isIdentifier, 'uid is not a valid identifier'], required: false },
    userName: { type: String, trim: true, validate: [strings.isValidString, 'userName is not a valid string'], required: false },
    passHash: { type: String, trim: true, validate: [strings.isValidString, 'passHash is not a valid string'], required: false },
    passSalt: { type: String, trim: true, validate: [strings.isValidString, 'passSalt is not a valid string'], required: false },
    _v: { type: Date, validate: [dates.isDate, '_v (auditVersionDate) is not a valid date'], required: false },
    _k: { type: Date, default: null, validate: [dates.isDateOrNull, '_k (auditDeletedDate) is not a valid date or null value'], required: true }
});

memberSchema.index({
    userName: 1,
    _k: 1
}, { unique: true });

var validateItem = function (item, callback) {
    if (!item) { return callback(new Error('No item to validate')); }
    if (typeof item._id !== 'undefined') { if (!uids.isIdentifier(item._id)) { return callback(new Error('_id (id) is not a valid String')); } else { item._id = strings.trimToNull(item._id); } }
    if (typeof item.uid !== 'undefined') { if (!uids.isIdentifier(item.uid)) { return callback(new Error('uid is not a valid String')); } else { item.uid = strings.trimToNull(item.uid); } }
    if (typeof item.userName !== 'undefined') { if (!strings.isValidString(item.userName)) { return callback(new Error('userName is not a valid String')); } else { item.userName = strings.trimToNull(item.userName); } }
    if (typeof item.passHash !== 'undefined') { if (!strings.isValidString(item.passHash)) { return callback(new Error('passHash is not a valid String')); } else { item.passHash = strings.trimToNull(item.passHash); } }
    if (typeof item.passSalt !== 'undefined') { if (!strings.isValidString(item.passSalt)) { return callback(new Error('passSalt is not a valid String')); } else { item.passSalt = strings.trimToNull(item.passSalt); } }
    if (typeof item._v !== 'undefined') { if (!strings.isDate(item._v)) { return callback(new Error('_v (auditVersionDate) is not a valid Date')); } else {  } }
    if (typeof item._k !== 'undefined') { if (!strings.isDateOrNull(item._k)) { return callback(new Error('_k (auditDeletedDate) is not a valid Date or null value')); } else {  } }
    return callback();
};
memberSchema.methods.validateItem = validateItem;

var toDto = function (item) {
    if (!item) { return null; }
    var dto = {};
    if (typeof item._id !== 'undefined') { dto.id = item._id; }
    if (typeof item.uid !== 'undefined') { dto.uid = item.uid; }
    if (typeof item.userName !== 'undefined') { dto.userName = item.userName; }
    if (typeof item.passHash !== 'undefined') { dto.passHash = item.passHash; }
    if (typeof item.passSalt !== 'undefined') { dto.passSalt = item.passSalt; }
    if (typeof item._v !== 'undefined') { dto.auditVersionDate = item._v; }
    if (typeof item._k !== 'undefined') { dto.auditDeletedDate = item._k; }
    return dto;
};
memberSchema.methods.toDto = toDto;

var toDtos = function (items) {
    if (!items || items.length < 1) { return null; }
    var i, dtos = [];
    for (i = 0; i < items.length; i += 1) {
        dtos.push(toDto(items[i]));
    }
    return dtos;
};
memberSchema.methods.toDto = toDto;

var toDtoFull = function (item) {
    if (!item) { return null; }
    var dto = {
        id: ((typeof item._id !== 'undefined') ? item._id : null),
        uid: ((typeof item.uid !== 'undefined') ? item.uid : null),
        userName: ((typeof item.userName !== 'undefined') ? item.userName : null),
        passHash: ((typeof item.passHash !== 'undefined') ? item.passHash : null),
        passSalt: ((typeof item.passSalt !== 'undefined') ? item.passSalt : null),
        auditVersionDate: ((typeof item._v !== 'undefined') ? item._v : null),
        auditDeletedDate: ((typeof item._k !== 'undefined') ? item._k : null)
    };
    return dto;
};
memberSchema.methods.toDtoFull = toDtoFull;

var toDtosFull = function (items) {
    if (!items || items.length < 1) { return null; }
    var i, dtos = [];
    for (i = 0; i < items.length; i += 1) {
        dtos.push(toDtoFull(items[i]));
    }
    return dtos;
};
memberSchema.methods.toDtosFull = toDtosFull;

var toItem = function (dto) {
    if (!dto) { return null; }
    var item = {};
    if (typeof dto.id !== 'undefined') { item._id = dto.id; }
    if (typeof dto.uid !== 'undefined') { item.uid = dto.uid; }
    if (typeof dto.userName !== 'undefined') { item.userName = dto.userName; }
    if (typeof dto.passHash !== 'undefined') { item.passHash = dto.passHash; }
    if (typeof dto.passSalt !== 'undefined') { item.passSalt = dto.passSalt; }
    if (typeof dto.auditVersionDate !== 'undefined') { item._v = dto.auditVersionDate; }
    if (typeof dto.auditDeletedDate !== 'undefined') { item._k = dto.auditDeletedDate; }
    return item;
};
memberSchema.methods.toItem = toItem;

var toItems = function toItems(dtos) {
    if (!dtos || dtos.length < 1) { return null; }
    var i, items = [];
    for (i = 0; i < dtos.length; i += 1) {
        items.push(toItem(dtos[i]));
    }
    return items;
};
memberSchema.methods.toItems = toItems;

var toItemFull = function toItemFull(dto) {
    if (!dto) { return null; }
    var item = {
        _id: ((typeof dto.id !== 'undefined') ? dto.id : null),
        uid: ((typeof dto.uid !== 'undefined') ? dto.uid : null),
        userName: ((typeof dto.userName !== 'undefined') ? dto.userName : null),
        passHash: ((typeof dto.passHash !== 'undefined') ? dto.passHash : null),
        passSalt: ((typeof dto.passSalt !== 'undefined') ? dto.passSalt : null),
        _v: ((typeof dto.auditVersionDate !== 'undefined') ? dto.auditVersionDate : null),
        _k: ((typeof dto.auditDeletedDate !== 'undefined') ? dto.auditDeletedDate : null)
    };
    return item;
};
memberSchema.methods.toItemFull = toItemFull;

var toItemsFull = function (dtos) {
    if (!dtos || dtos.length < 1) { return null; }
    var i, items = [];
    for (i = 0; i < dtos.length; i += 1) {
        items.push(toItemFull(dtos[i]));
    }
    return items;
};
memberSchema.methods.toItemsFull = toItemsFull;

var getAll = function (callback) {
    var query = { _k: null };
    mongoose.model('Member').find(query, function (err, items) {
        if (err) { return callback(err); }
        return callback(null, toDtos(items));
    });
};
memberSchema.methods.getAll = getAll;

var getById = function (id, callback) {
    var query = { _id: id, _k: null };
    validateItem(query, function (err) {
        if (err) { return callback(err); }
        mongoose.model('Member').findOne(query, function (err, item) {
            if (err) { return callback(err); }
            if (item) { return callback(null, toDto(item)); }
            return callback();
        });
    });
};
memberSchema.methods.getById = getById;

var getOneByUserName = function (userName, callback) {
    var query = {
        userName: userName,
        _k: null
    };
    validateItem(query, function (err) {
        if (err) { return callback(err); }
        mongoose.model('Member').findOne(query, function (err, item) {
            if (err) { return callback(err); }
            if (item) { return callback(null, toDto(item)); }
            return callback();
        });
    });
};
memberSchema.methods.getOneByUserName = getOneByUserName;

var createNew = function (uid, userName, passHash, passSalt, callback) {
    var data = {
        uid: uid,
        userName: userName,
        passHash: passHash,
        passSalt: passSalt,
        _v: moment().utc().toDate(),
        _k: null
    };
    validateItem(data, function (err) {
        if (err) { return callback(err); }
        var newItem = new member(data);
        newItem.save(function (err, item) {
            if (err) { return callback(err); }
            return callback(null, toDto(item));
        });
    });
};
memberSchema.methods.createNew = createNew;

var createNewOrGet = function (uid, userName, passHash, passSalt, suppressError, callback) {
    var dupErr = suppressError ? null : (new Error('Duplicate Member detected'));
    getOneByUserName(userName, function (err, existing) {
        if (err) { return callback(err); }
        if (existing) { return callback(dupErr, existing); }
        return createNew(uid, userName, passHash, passSalt, callback);
    });
};
memberSchema.methods.createNewOrGet = createNewOrGet;

var modifyMany = function (queryDto, updateDto, callback) {
    if (!updateDto) { callback(new Error('Nothing to update')); }
    updateDto.auditVersionDate = moment().utc().toDate();
    var query = toItem(queryDto),
        update = toItem(updateDto);
    validateItem(query, function (err) {
        if (err) { return callback(new Error('Invalid query: ' + err.message)); }
        validateItem(update, function (err) {
            if (err) { return callback(new Error('Invalid update: ' + err.message)); }
            return mongoose.model('Member').update(query, update, callback);
        });
    });
};
memberSchema.methods.modifyMany = modifyMany;

var modifyOne = function (queryDto, updateDto, callback) {
    if (!updateDto) { return callback(new Error('Nothing to update')); }
    updateDto.auditVersionDate = moment().utc().toDate();
    var query = toItem(queryDto),
        update = toItem(updateDto);
    validateItem(query, function (err) {
        if (err) { return callback(new Error('Invalid query: ' + err.message)); }
        validateItem(update, function (err) {
            if (err) { return callback(new Error('Invalid update: ' + err.message)); }
            mongoose.model('Member').findOneAndUpdate(query, update, function (err, item) {
                if (err) { return callback(err); }
                if (item) { return callback(null, toDto(item)); }
                return callback();
            });
        });
    });
};
memberSchema.methods.modifyOne = modifyOne;

var deleteMany = function (queryDto, callback) {
    var updateDto = { auditDeletedDate: moment().utc().toDate() };
    return modifyMany(queryDto, updateDto, callback);
};
memberSchema.methods.deleteMany = deleteMany;

var deleteOne = function (queryDto, callback) {
    var updateDto = { auditDeletedDate: moment().utc().toDate() };
    return modifyOne(queryDto, updateDto, callback);
};
memberSchema.methods.deleteOne = deleteOne;

var member = mongoose.model('Member', memberSchema);

module.exports = member;
\$\endgroup\$
3
  • \$\begingroup\$ Please note that your question must contain the code you want reviewed to be on-topic. It is ok to add additional links for context (external code is not subject to review though), but the code you post here should be understandable without visiting external sources. \$\endgroup\$
    – tim
    Apr 2, 2015 at 19:52
  • \$\begingroup\$ @tim: The review is of the project, not a single snippet or file. As you'll see from the history of the question, I originally provided source in-line and it led to confusion. If a single snippet had a question, wouldn't StackOverflow be more suitable? \$\endgroup\$ Apr 2, 2015 at 19:55
  • \$\begingroup\$ No, stackoverflow would not really be suitable for working code that you want to make better, not even snippets. That's what this site is for. We review small and big code (although expect less answers for gigantic code dumps). If your code is just too large (there is a character limit for questions), try to break it down and post multiple questions (this will also increase the amount and quality of answers you will receive). Anyways, in it's current form, your question is off-topic and will probably soon be closed. I would suggest you roll it back to the last revision for now. \$\endgroup\$
    – tim
    Apr 2, 2015 at 20:03

2 Answers 2

1
+50
\$\begingroup\$

I've looked at the files on GitHub. There are a few things I would change.

  1. Allow a Mongoose query to be sent in.

  2. Provide caching on the server. You're already generating everything. Why force the user to create this?

  3. Provide an Angular UI. You are basically scaffolding. The only thing missing is a user interface.

  4. Use regions in your templates so users can customize the generated files without fear of their work being overwritten.

  5. Consider moving your templates to something like Yeoman. I don't know anyone that owns CodeSmith. Until CodeSmith runs on Mac I won't be buying it and I hate using virtual machines.

Everything else looks great. I disagree with the guy above. Generated files are usually never touched and it is clear this is the intent of these files. I like the proxy and service files you generate. If someone is using these then the generated files will never matter.

\$\endgroup\$
0
\$\begingroup\$

I find your comments confusing:

//Default (No Schema) (2 tables) - BEGIN

Default for what? No Schema for what? Why 2 tables? Begin of what?


bogusCodeRouter

I know good naming is hard but maybe a name revealing more about what the Router is doing would make it easy to read your code.

Also you don't seem to provide the files defining the routes and both links to Github seems to be dead (which is why you need to provide the files, not the links!).


Are the files you provide correspond to ones used by others? The best practice is to write the actual file name at the top of the file in the comments, otherwise there is no way I can find out.


You are using the non-standard package 'dzutils' which requires at least some explanation or code or better both.


memberSchema looks hardcoded and non-reusable to me, but then again, I don't know its purpose and the level of abstraction.


Your code has many similar looking lines, e.g. of the type

if (typeof a == 'undefined') {x=y}
  • It would be DRYer to make it a function like adjust(a,x,y) and reuse it.

  • Or use _.isUndefined(a) from the Lodash/Underscore library.

\$\endgroup\$
5
  • \$\begingroup\$ Thanks for the input, however many of the points you've mentioned are due to these files being GENERATED. For example, the use of a typeof vs simply if (a) is a perfect example. Since some of the fields may be boolean values, the typeof is the only version that could be used to check for missing parameters if (a) would cause a failure if the variable IS a boolean AND true. \$\endgroup\$ Apr 6, 2015 at 13:36
  • \$\begingroup\$ Good idea about the "Default" comment. This was the default OWNER of the source table. I've modified the comments to clarify this. The reason there is only two tables in this section is due to the fact that these two tables are the only two that do not have a specific owner assigned in the source database. \$\endgroup\$ Apr 6, 2015 at 13:43
  • \$\begingroup\$ Names like bogusCodeRouter and memberSchema are named for the tables they provide functionality for. Since the generated application is essentially a CRUD web API application, each table (ie, the "Member" table, the "BogusCode" table, etc.) has certain generated items. These names are the generated equivalent and were chosen to increase the verbosity of the generated output. \$\endgroup\$ Apr 6, 2015 at 13:48
  • \$\begingroup\$ I've also added logic to embed the generated file name in each file that is output. Thanks for the suggestion. \$\endgroup\$ Apr 6, 2015 at 13:49
  • \$\begingroup\$ @FredLackey Thanks for the comments. (1) GENERATED is not an excuse! 1st - the reader does not know it, 2nd - confusing unintelligible comments remains harming code quality, generated or not. (2) You are right about if(a), I have changed it to much cleaner solution. (3) Not sure what tables you refer to. Remember - the reader did not spend days working on your code, so you need to help him as much as possible. If table is important keyword, make it part of your variable naming! (4) When you update your question, make sure to mark is as EDIT or like, so the reader will recognize it. \$\endgroup\$ Apr 7, 2015 at 3:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.