I'm Lucas Michailian 🇦🇷
I love creating products and learning about new technologies 🚀
Also Tech Leader at Yuno Payments #frontend #react #javascript #node #rust
License: MIT License
Me deja crear/actualizar clientes con el mismo numero de tarjeta
Cuando ingreso a /services/charges y la tarjeta no existe o la tarjeta existe y el id de servicio es incorrecto me da error 500 deberia ser 404 con un mensaje mas apropiado.
Cuando ingreso http://api-donlobo.rockerlabs.co/api/v1/credits/customers/:card
con un :card invalido retorna
{ "error": false, "credit": { "id": null, "full_name": null, "phone": null, "credits": null } }
deberia devolver 404
Al querer obtener el credito del cliente mediante /credit/customer/:card me arroja el siguiente error
{ "error": true, "message": "select
customers.
id,
customers.
full_name,
customers.
phone, sum(
credits.
amount) as
creditsfrom
customersinner join
creditson
customers.
id=
credits.
customer_idwhere
credits.
expired= false and
customers.
card = '123123' - ER_MIX_OF_GROUP_FUNC_AND_FIELDS: In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'don_lobo_api.customers.id'; this is incompatible with sql_mode=only_full_group_by" }
Al acceder a GET http://localhost:3333/api/v1/customers obtengo el siguiente error
{"error":{"message":"select customers
.id
, customers
.full_name
, customers
.phone
, customers
.card
, sum(credits
.amount
) as credits
from customers
inner join credits
on customers
.id
= credits
.customer_id
where customers
.deleted_at
is null and credits
.expired
= false - ER_MIX_OF_GROUP_FUNC_AND_FIELDS: In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'don_lobo_api.customers.id'; this is incompatible with sql_mode=only_full_group_by","name":"Error","status":500,"frames":[{"file":"node_modules/mysql/lib/protocol/sequences/Sequence.js","method":"Query.Sequence._packetToError","line":52,"column":14,"context":{"start":47,"pre":" return Boolean(this._callback) || listenerCount(this, 'error') > 1;\n};\n\nSequence.prototype._packetToError = function(packet) {\n var code = ErrorConstants[packet.errno] || 'UNKNOWN_CODE_PLEASE_REPORT';","line":" var err = new Error(code + ': ' + packet.message);","post":" err.code = code;\n err.errno = packet.errno;\n\n err.sqlMessage = packet.message;\n err.sqlState = packet.sqlState;"}},{"file":"node_modules/mysql/lib/protocol/sequences/Query.js","method":"Query.ErrorPacket","line":77,"column":18,"context":{"start":72,"pre":" this._handleFinalResultPacket(packet);\n }\n};\n\nQuery.prototype['ErrorPacket'] = function(packet) {","line":" var err = this._packetToError(packet);","post":"\n var results = (this._results.length > 0)\n ? this._results\n : undefined;\n"}},{"file":"node_modules/mysql/lib/protocol/Protocol.js","method":"Protocol._parsePacket","line":279,"column":23,"context":{"start":274,"pre":"\n this._delegateError(err);\n return;\n }\n","line":" sequencepacketName;","post":"};\n\nProtocol.prototype._parsePacketDebug = function _parsePacketDebug(packet) {\n try {\n packet.parse(this._parser);"}},{"file":"node_modules/mysql/lib/protocol/Parser.js","method":"Parser.write","line":76,"column":12,"context":{"start":71,"pre":"\n // Try...finally to ensure exception safety. Unfortunately this is costing\n // us up to ~10% performance in some benchmarks.\n var hadException = true;\n try {","line":" this._onPacket(this.packetHeader);","post":" hadException = false;\n } catch (err) {\n if (!err || typeof err.code !== 'string' || err.code.substr(0, 7) !== 'PARSER') {\n throw err; // Rethrow non-MySQL errors\n }"}},{"file":"node_modules/mysql/lib/protocol/Protocol.js","method":"Protocol.write","line":39,"column":16,"context":{"start":34,"pre":" config : this._config\n });\n}\n\nProtocol.prototype.write = function(buffer) {","line":" this._parser.write(buffer);","post":" return true;\n};\n\nProtocol.prototype.handshake = function handshake(options, callback) {\n if (typeof options === 'function') {"}},{"file":"node_modules/mysql/lib/Connection.js","method":null,"line":103,"column":28,"context":{"start":98,"pre":" var connection = this;\n this._protocol.on('data', function(data) {\n connection._socket.write(data);\n });\n this._socket.on('data', function(data) {","line":" connection._protocol.write(data);","post":" });\n this._protocol.on('end', function() {\n connection._socket.end();\n });\n this._socket.on('end', function() {"}},{"file":"events.js","method":"emitOne","line":96,"column":13,"context":{}},{"file":"events.js","method":"Socket.emit","line":188,"column":7,"context":{}},{"file":"_stream_readable.js","method":"readableAddChunk","line":176,"column":18,"context":{}},{"file":"_stream_readable.js","method":"Socket.Readable.push","line":134,"column":10,"context":{}},{"file":"net.js","method":"TCP.onread","line":548,"column":20,"context":{}},{"file":"node_modules/mysql/lib/protocol/Protocol.js","method":"Protocol._enqueue","line":145,"column":48,"context":{"start":140,"pre":" return sequence;\n }\n\n if (this._config.trace) {\n // Long stack trace support","line":" sequence._callSite = sequence._callSite || new Error();","post":" }\n\n this._queue.push(sequence);\n this.emit('enqueue', sequence);\n"}},{"file":"node_modules/mysql/lib/Connection.js","method":"Connection.query","line":208,"column":25,"context":{"start":203,"pre":" query.sql = this.format(query.sql, query.values);\n }\n\n this._implyConnect();\n","line":" return this._protocol._enqueue(query);","post":"};\n\nConnection.prototype.ping = function ping(options, callback) {\n if (!callback && typeof options === 'function') {\n callback = options;"}},{"file":"node_modules/knex/lib/dialects/mysql/index.js","method":null,"line":152,"column":18,"context":{"start":147,"pre":" var _obj = obj,\n sql = _obj.sql;\n\n if (!sql) return resolver();\n if (obj.options) sql = (0, _assign3.default)({ sql: sql }, obj.options);","line":" connection.query(sql, obj.bindings, function (err, rows, fields) {","post":" if (err) return rejecter(err);\n obj.response = [rows, fields];\n resolver(obj);\n });\n });"}},{"file":"node_modules/knex/lib/dialects/mysql/index.js","method":"Client_MySQL._query","line":146,"column":12,"context":{"start":141,"pre":"\n // Runs the query on the specified connection, providing the bindings\n // and any other necessary prep work.\n _query: function _query(connection, obj) {\n if (!obj || typeof obj === 'string') obj = { sql: obj };","line":" return new _bluebird2.default(function (resolver, rejecter) {","post":" var _obj = obj,\n sql = _obj.sql;\n\n if (!sql) return resolver();\n if (obj.options) sql = (0, _assign3.default)({ sql: sql }, obj.options);"}},{"file":"node_modules/knex/lib/client.js","method":"Client_MySQL.query","line":197,"column":17,"context":{"start":192,"pre":" if (typeof obj === 'string') obj = { sql: obj };\n obj.bindings = this.prepBindings(obj.bindings);\n debugQuery(obj.sql);\n this.emit('query', (0, _assign3.default)({ __knexUid: connection.__knexUid }, obj));\n debugBindings(obj.bindings);","line":" return this._query(connection, obj).catch(function (err) {","post":" err.message = _this2._formatQuery(obj.sql, obj.bindings) + ' - ' + err.message;\n _this2.emit('query-error', err, (0, _assign3.default)({ __knexUid: connection.__knexUid }, obj));\n throw err;\n });\n },"}},{"file":"node_modules/knex/lib/runner.js","method":null,"line":146,"column":36,"context":{"start":141,"pre":" query: _bluebird2.default.method(function (obj) {\n var _this = this;\n\n this.builder.emit('query', (0, _assign3.default)({ __knexUid: this.connection.__knexUid }, obj));\n var runner = this;","line":" var queryPromise = this.client.query(this.connection, obj);","post":"\n if (obj.timeout) {\n queryPromise = queryPromise.timeout(obj.timeout);\n }\n"}},{"file":"node_modules/knex/lib/runner.js","method":null,"line":65,"column":21,"context":{"start":60,"pre":" }\n\n if ((0, _isArray3.default)(sql)) {\n return runner.queryArray(sql);\n }","line":" return runner.query(sql);","post":" })\n\n // If there are any "error" listeners, we fire an error event\n // and then re-throw the error to be eventually handled by\n // the promise chain. Useful if you're wrapping in a custom Promise
."}},{"file":"timers.js","method":"runCallback","line":637,"column":20,"context":{}},{"file":"timers.js","method":"tryOnImmediate","line":610,"column":5,"context":{}},{"file":"timers.js","method":"processImmediate [as _immediateCallback]","line":582,"column":5,"context":{}},{"file":"node_modules/knex/lib/runner.js","method":"Runner.run","line":51,"column":31,"context":{"start":46,"pre":" // "Run" the target, calling "toSQL" on the builder, returning\n // an object or array of queries to run, each of which are run on\n // a single connection.\n run: function run() {\n var runner = this;","line":" return _bluebird2.default.using(this.ensureConnection(), function (connection) {","post":" runner.connection = connection;\n\n runner.client.emit('start', runner.builder);\n runner.builder.emit('start', runner.builder);\n var sql = runner.builder.toSQL();"}},{"file":"node_modules/knex/lib/interface.js","method":"Builder.Target.then","line":35,"column":43,"context":{"start":30,"pre":" }).join(';\n');\n };\n\n // Create a new instance of the Runner
, passing in the current object.\n Target.prototype.then = function () /* onFulfilled, onRejected */{","line":" var result = this.client.runner(this).run();","post":" return result.then.apply(result, arguments);\n };\n\n // Add additional "options" to the builder. Typically used for client specific\n // items, like the mysql
and sqlite3
drivers."}},{"file":"node_modules/co/index.js","method":"next","line":100,"column":51,"context":{"start":95,"pre":" */\n\n function next(ret) {\n if (ret.done) return resolve(ret.value);\n var value = toPromise.call(ctx, ret.value);","line":" if (value && isPromise(value)) return value.then(onFulfilled, onRejected);","post":" return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, '\n + 'but the following object was passed: "' + String(ret.value) + '"'));\n }\n });\n}"}},{"file":"node_modules/co/index.js","method":"onFulfilled","line":69,"column":7,"context":{"start":64,"pre":" try {\n ret = gen.next(res);\n } catch (e) {\n return reject(e);\n }","line":" next(ret);","post":" }\n\n /\n * @param {Error} err\n * @return {Promise}"}},{"file":"node_modules/co/index.js","method":null,"line":54,"column":5,"context":{"start":49,"pre":" // see https://github.com/tj/co/issues/180\n return new Promise(function(resolve, reject) {\n if (typeof gen === 'function') gen = gen.apply(ctx, args);\n if (!gen || typeof gen.next !== 'function') return resolve(gen);\n","line":" onFulfilled();","post":"\n /\n * @param {Mixed} res\n * @return {Promise}\n * @api private"}},{"file":"node_modules/co/index.js","method":"co","line":50,"column":10,"context":{"start":45,"pre":" var args = slice.call(arguments, 1)\n\n // we wrap everything in a promise to avoid promise chaining,\n // which leads to memory leak errors.\n // see https://github.com/tj/co/issues/180","line":" return new Promise(function(resolve, reject) {","post":" if (typeof gen === 'function') gen = gen.apply(ctx, args);\n if (!gen || typeof gen.next !== 'function') return resolve(gen);\n\n onFulfilled();\n"}},{"file":"node_modules/co/index.js","method":"toPromise","line":118,"column":63,"context":{"start":113,"pre":" */\n\nfunction toPromise(obj) {\n if (!obj) return obj;\n if (isPromise(obj)) return obj;","line":" if (isGeneratorFunction(obj) || isGenerator(obj)) return co.call(this, obj);","post":" if ('function' == typeof obj) return thunkToPromise.call(this, obj);\n if (Array.isArray(obj)) return arrayToPromise.call(this, obj);\n if (isObject(obj)) return objectToPromise.call(this, obj);\n return obj;\n}"}},{"file":"node_modules/co/index.js","method":"next","line":99,"column":29,"context":{"start":94,"pre":" * @api private\n */\n\n function next(ret) {\n if (ret.done) return resolve(ret.value);","line":" var value = toPromise.call(ctx, ret.value);","post":" if (value && isPromise(value)) return value.then(onFulfilled, onRejected);\n return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, '\n + 'but the following object was passed: "' + String(ret.value) + '"'));\n }\n });"}},{"file":"node_modules/co/index.js","method":"onFulfilled","line":69,"column":7,"context":{"start":64,"pre":" try {\n ret = gen.next(res);\n } catch (e) {\n return reject(e);\n }","line":" next(ret);","post":" }\n\n /**\n * @param {Error} err\n * @return {Promise}"}}]}}
Actualmente las validaciones son alfa numericas, deben ser solo numericas.
Los nombres para las rutas siempre son en plural, esto aplica para GET, POST, DELETE, UPDATE, PUT
Cuando quiero actualizar un cliente que no existe, el sistema arroja un error 500 esto es incorrecto debe arrojar un 404.
Falta un recurso ej: '/me' para que me devuelva los datos del user logueado
Cuando quiero eliminar un cliente que no existe el sistema arroja un error 500 esto es incorrecto deberia arrojar un 404
En /services/charges si cargo un servicio con mas valor al cargado, no tengo ningun mensaje de que no tengo el saldo suficiente y me deja el saldo negativo
Traducir el mensaje que arroja la validacion de tarjeta de credito al actualizar
Falta el campo cumpleaños, llamarlo birthday y que sea datetime
El endponint /transaction/customer/:id deberia traer el total hasta la fecha
Si no completo el username el mensaje que aparece es El email es un campo requerido.
Cuando accedo a la raiz del api me muestra una vista deberiamos poner que solo muestre un mensaje como API OK
http://api-donlobo.rockerlabs.co/
http://api-donlobo.rockerlabs.co/api/v1
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.