diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..7d8a497 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,4 @@ +dist/ +build/ +coverage/ +node_modules/ diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 73133d4..ca1ee35 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,3 +1,4 @@ +<<<<<<< HEAD 'use strict'; module.exports = { @@ -26,26 +27,70 @@ module.exports = { 'error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }, ], - - // Allow explicit `any` with a warning instead of hard error (relax for now) - '@typescript-eslint/no-explicit-any': 'warn', - - // Enforce consistent type imports - '@typescript-eslint/consistent-type-imports': [ + 'airbnb-typescript/base', + ], + rules: { + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }], + '@typescript-eslint/quotes': ['error', 'double'], + 'import/no-extraneous-dependencies': ['error', { devDependencies: true }], + 'import/extensions': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/naming-convention': [ + 'error', + { + selector: 'variableLike', + format: ['camelCase', 'PascalCase', 'UPPER_CASE'], + leadingUnderscore: 'allow', + }, + ], + 'node/no-missing-import': 'off', + 'indent': 'off', + '@typescript-eslint/indent': 'off', + }, + overrides: [ + { + files: ['**/*.test.ts'], + rules: { + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }], + }, + }, + ], + ignorePatterns: ['dist/', 'node_modules/', 'coverage/', 'build/'], + es2021: true, + jest: true, + }, + plugins: ['@typescript-eslint', 'import', 'node', 'promise'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'airbnb-typescript/base', + ], + rules: { + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }], + '@typescript-eslint/quotes': ['error', 'double'], + 'import/no-extraneous-dependencies': ['error', { devDependencies: true }], + 'import/extensions': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/naming-convention': [ 'error', - { prefer: 'type-imports', fixStyle: 'inline-type-imports' }, + { + selector: 'variableLike', + format: ['camelCase', 'PascalCase', 'UPPER_CASE'], + leadingUnderscore: 'allow', + }, ], - - // No floating promises — important for async route handlers - '@typescript-eslint/no-floating-promises': 'error', - - // Disallow require() in ESM codebase - '@typescript-eslint/no-require-imports': 'error', + 'node/no-missing-import': 'off', + 'indent': 'off', + '@typescript-eslint/indent': 'off', }, - ignorePatterns: [ - 'dist/', - 'node_modules/', - 'coverage/', - '*.cjs', // ignore this file itself + overrides: [ + { + files: ['**/*.test.ts'], + rules: { + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }], + }, + }, ], + ignorePatterns: ['dist/', 'node_modules/', 'coverage/', 'build/'], +>>>>>>> 4e2f84e (chore: configure ESLint for backend TypeScript) }; diff --git a/README.md b/README.md index 84fb2d5..cf4aa05 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,16 @@ npm run test:watch - `GET /api/credit/lines/:id` — Get credit line by id (placeholder) - `POST /api/risk/evaluate` — Request risk evaluation; body: `{ "walletAddress": "..." }` +## Linting and formatting + +Consistent coding practices are enforced via ESLint configured for TypeScript. Run the linter with: + +```bash +npm run lint # analyze source files under src/ +``` + +The configuration lives in `.eslintrc.cjs` and common ignores are listed in `.eslintignore`. + ## Project layout ``` diff --git a/coverage/.tmp/coverage-0.json b/coverage/.tmp/coverage-0.json new file mode 100644 index 0000000..26f5f91 --- /dev/null +++ b/coverage/.tmp/coverage-0.json @@ -0,0 +1 @@ +{"result":[{"scriptId":"375","url":"file:///home/samaro/cred/Creditra-Backend/src/__test__/creditService.test.ts","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":29158,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":13,"endOffset":29158,"count":1},{"startOffset":566,"endOffset":29157,"count":0}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":602,"endOffset":650,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":684,"endOffset":2309,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":2340,"endOffset":2909,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":2942,"endOffset":3555,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":3590,"endOffset":7033,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":7066,"endOffset":10040,"count":0}],"isBlockCoverage":false}]}]} \ No newline at end of file diff --git a/coverage/.tmp/coverage-1.json b/coverage/.tmp/coverage-1.json new file mode 100644 index 0000000..79addda --- /dev/null +++ b/coverage/.tmp/coverage-1.json @@ -0,0 +1 @@ +{"result":[{"scriptId":"375","url":"file:///home/samaro/cred/Creditra-Backend/src/__test__/horizonListener.test.ts","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":42421,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":13,"endOffset":42421,"count":1}],"isBlockCoverage":true},{"functionName":"silenceConsole","ranges":[{"startOffset":397,"endOffset":615,"count":33}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":473,"endOffset":484,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":536,"endOffset":547,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":600,"endOffset":611,"count":0}],"isBlockCoverage":false},{"functionName":"restoreConsole","ranges":[{"startOffset":616,"endOffset":741,"count":33},{"startOffset":669,"endOffset":673,"count":0},{"startOffset":701,"endOffset":705,"count":0},{"startOffset":734,"endOffset":738,"count":0}],"isBlockCoverage":true},{"functionName":"withEnv","ranges":[{"startOffset":742,"endOffset":1120,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1132,"endOffset":1278,"count":33},{"startOffset":1201,"endOffset":1277,"count":0}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1291,"endOffset":1461,"count":33},{"startOffset":1340,"endOffset":1369,"count":0}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1492,"endOffset":3620,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1559,"endOffset":1998,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":2036,"endOffset":2253,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":2292,"endOffset":2452,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":2512,"endOffset":2754,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":2808,"endOffset":3021,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":3091,"endOffset":3229,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":3273,"endOffset":3420,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":3467,"endOffset":3616,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":3661,"endOffset":4472,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":3720,"endOffset":3848,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":3904,"endOffset":4181,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":4233,"endOffset":4468,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":4495,"endOffset":6355,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":4532,"endOffset":4674,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":4727,"endOffset":5059,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":5114,"endOffset":5684,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":5745,"endOffset":6085,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":6128,"endOffset":6351,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":6377,"endOffset":8004,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":6415,"endOffset":6592,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":6654,"endOffset":7142,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":7199,"endOffset":7372,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":7406,"endOffset":7666,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":7724,"endOffset":8000,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":8052,"endOffset":10351,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":8119,"endOffset":8461,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":8523,"endOffset":8923,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":8987,"endOffset":9312,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":9393,"endOffset":9887,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":9944,"endOffset":10347,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":10377,"endOffset":12791,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":10601,"endOffset":10705,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":10753,"endOffset":10969,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":11034,"endOffset":11463,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":11521,"endOffset":11709,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":11772,"endOffset":11965,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":12033,"endOffset":12364,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":12425,"endOffset":12787,"count":0}],"isBlockCoverage":false}]},{"scriptId":"376","url":"file:///home/samaro/cred/Creditra-Backend/src/services/horizonListener.ts","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":13746,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":13,"endOffset":13746,"count":1}],"isBlockCoverage":true},{"functionName":"resolveConfig","ranges":[{"startOffset":284,"endOffset":792,"count":0}],"isBlockCoverage":false},{"functionName":"get","ranges":[{"startOffset":894,"endOffset":923,"count":0}],"isBlockCoverage":false},{"functionName":"onEvent","ranges":[{"startOffset":927,"endOffset":987,"count":0}],"isBlockCoverage":false},{"functionName":"get","ranges":[{"startOffset":1083,"endOffset":1106,"count":0}],"isBlockCoverage":false},{"functionName":"clearEventHandlers","ranges":[{"startOffset":1110,"endOffset":1171,"count":33}],"isBlockCoverage":true},{"functionName":"get","ranges":[{"startOffset":1278,"endOffset":1312,"count":33}],"isBlockCoverage":true},{"functionName":"dispatchEvent","ranges":[{"startOffset":1316,"endOffset":1565,"count":0}],"isBlockCoverage":false},{"functionName":"pollOnce","ranges":[{"startOffset":1566,"endOffset":2297,"count":0}],"isBlockCoverage":false},{"functionName":"get","ranges":[{"startOffset":2394,"endOffset":2418,"count":0}],"isBlockCoverage":false},{"functionName":"isRunning","ranges":[{"startOffset":2422,"endOffset":2464,"count":33}],"isBlockCoverage":true},{"functionName":"get","ranges":[{"startOffset":2562,"endOffset":2587,"count":33}],"isBlockCoverage":true},{"functionName":"getConfig","ranges":[{"startOffset":2591,"endOffset":2638,"count":0}],"isBlockCoverage":false},{"functionName":"get","ranges":[{"startOffset":2736,"endOffset":2761,"count":0}],"isBlockCoverage":false},{"functionName":"start","ranges":[{"startOffset":2765,"endOffset":3413,"count":0}],"isBlockCoverage":false},{"functionName":"get","ranges":[{"startOffset":3507,"endOffset":3528,"count":0}],"isBlockCoverage":false},{"functionName":"stop","ranges":[{"startOffset":3532,"endOffset":3846,"count":0}],"isBlockCoverage":false},{"functionName":"get","ranges":[{"startOffset":3939,"endOffset":3959,"count":0}],"isBlockCoverage":false}]}]} \ No newline at end of file diff --git a/coverage/.tmp/coverage-2.json b/coverage/.tmp/coverage-2.json new file mode 100644 index 0000000..9ae9a81 --- /dev/null +++ b/coverage/.tmp/coverage-2.json @@ -0,0 +1 @@ +{"result":[{"scriptId":"375","url":"file:///home/samaro/cred/Creditra-Backend/src/__test__/creditRoute.test.ts","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":28745,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":13,"endOffset":28745,"count":1},{"startOffset":384,"endOffset":28744,"count":0}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1055,"endOffset":1178,"count":0}],"isBlockCoverage":false},{"functionName":"buildApp","ranges":[{"startOffset":1239,"endOffset":1429,"count":0}],"isBlockCoverage":false},{"functionName":"allowAdmin","ranges":[{"startOffset":1529,"endOffset":1620,"count":0}],"isBlockCoverage":false},{"functionName":"denyAdmin","ranges":[{"startOffset":1621,"endOffset":1806,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1840,"endOffset":1904,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1939,"endOffset":1977,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":2014,"endOffset":2764,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":2805,"endOffset":3606,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":3672,"endOffset":4357,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":4424,"endOffset":6302,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":6366,"endOffset":7045,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":7110,"endOffset":9579,"count":0}],"isBlockCoverage":false}]}]} \ No newline at end of file diff --git a/coverage/.tmp/coverage-3.json b/coverage/.tmp/coverage-3.json new file mode 100644 index 0000000..5b472b9 --- /dev/null +++ b/coverage/.tmp/coverage-3.json @@ -0,0 +1 @@ +{"result":[{"scriptId":"375","url":"file:///home/samaro/cred/Creditra-Backend/src/__test__/riskService.test.ts","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":19908,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":13,"endOffset":19908,"count":1},{"startOffset":354,"endOffset":19907,"count":0}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":555,"endOffset":2194,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":2228,"endOffset":3202,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":3234,"endOffset":6310,"count":0}],"isBlockCoverage":false}]}]} \ No newline at end of file diff --git a/coverage/.tmp/coverage-4.json b/coverage/.tmp/coverage-4.json new file mode 100644 index 0000000..7c34283 --- /dev/null +++ b/coverage/.tmp/coverage-4.json @@ -0,0 +1 @@ +{"result":[{"scriptId":"375","url":"file:///home/samaro/cred/Creditra-Backend/src/__test__/riskRoute.test.ts","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":15957,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":13,"endOffset":15957,"count":1},{"startOffset":384,"endOffset":15956,"count":0}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":795,"endOffset":856,"count":0}],"isBlockCoverage":false},{"functionName":"buildApp","ranges":[{"startOffset":926,"endOffset":1114,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1436,"endOffset":5283,"count":0}],"isBlockCoverage":false}]}]} \ No newline at end of file diff --git a/coverage/.tmp/coverage-5.json b/coverage/.tmp/coverage-5.json new file mode 100644 index 0000000..c1bf4be --- /dev/null +++ b/coverage/.tmp/coverage-5.json @@ -0,0 +1 @@ +{"result":[{"scriptId":"375","url":"file:///home/samaro/cred/Creditra-Backend/src/db/migrations.test.ts","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":16086,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":13,"endOffset":16086,"count":1}],"isBlockCoverage":true},{"functionName":"createMockClient","ranges":[{"startOffset":555,"endOffset":773,"count":6}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":828,"endOffset":1232,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":888,"endOffset":1029,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1091,"endOffset":1228,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1292,"endOffset":1684,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1384,"endOffset":1680,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1740,"endOffset":2674,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1830,"endOffset":2278,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":2358,"endOffset":2670,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":2730,"endOffset":3320,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":2809,"endOffset":3316,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":3205,"endOffset":3230,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":3372,"endOffset":4129,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":3453,"endOffset":4125,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":3586,"endOffset":3628,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":3892,"endOffset":3973,"count":2}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":4187,"endOffset":5368,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":4258,"endOffset":4740,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":4547,"endOffset":4589,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":4823,"endOffset":5364,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":5079,"endOffset":5121,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":5421,"endOffset":5700,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":5491,"endOffset":5696,"count":1}],"isBlockCoverage":true}]},{"scriptId":"377","url":"file:///home/samaro/cred/Creditra-Backend/src/db/migrations.ts","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":9334,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":13,"endOffset":9334,"count":1}],"isBlockCoverage":true},{"functionName":"get","ranges":[{"startOffset":773,"endOffset":804,"count":1}],"isBlockCoverage":true},{"functionName":"ensureSchemaMigrations","ranges":[{"startOffset":808,"endOffset":904,"count":5}],"isBlockCoverage":true},{"functionName":"get","ranges":[{"startOffset":1015,"endOffset":1053,"count":1}],"isBlockCoverage":true},{"functionName":"listMigrationFiles","ranges":[{"startOffset":1057,"endOffset":1304,"count":3}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1214,"endOffset":1258,"count":6}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1264,"endOffset":1277,"count":3}],"isBlockCoverage":true},{"functionName":"get","ranges":[{"startOffset":1411,"endOffset":1445,"count":1}],"isBlockCoverage":true},{"functionName":"versionFromFilename","ranges":[{"startOffset":1449,"endOffset":1574,"count":6},{"startOffset":1524,"endOffset":1540,"count":1},{"startOffset":1540,"endOffset":1573,"count":5}],"isBlockCoverage":true},{"functionName":"get","ranges":[{"startOffset":1682,"endOffset":1717,"count":2}],"isBlockCoverage":true},{"functionName":"getAppliedVersions","ranges":[{"startOffset":1721,"endOffset":1974,"count":4}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1954,"endOffset":1970,"count":2}],"isBlockCoverage":true},{"functionName":"get","ranges":[{"startOffset":2081,"endOffset":2115,"count":2}],"isBlockCoverage":true},{"functionName":"applyMigration","ranges":[{"startOffset":2119,"endOffset":2548,"count":2}],"isBlockCoverage":true},{"functionName":"get","ranges":[{"startOffset":2651,"endOffset":2681,"count":1}],"isBlockCoverage":true},{"functionName":"runPendingMigrations","ranges":[{"startOffset":2685,"endOffset":3158,"count":2},{"startOffset":3022,"endOffset":3142,"count":1}],"isBlockCoverage":true},{"functionName":"get","ranges":[{"startOffset":3267,"endOffset":3303,"count":2}],"isBlockCoverage":true}]}]} \ No newline at end of file diff --git a/coverage/.tmp/coverage-6.json b/coverage/.tmp/coverage-6.json new file mode 100644 index 0000000..97352e8 --- /dev/null +++ b/coverage/.tmp/coverage-6.json @@ -0,0 +1 @@ +{"result":[{"scriptId":"375","url":"file:///home/samaro/cred/Creditra-Backend/src/__test__/adminAuth.test.ts","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":12905,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":13,"endOffset":12905,"count":1},{"startOffset":384,"endOffset":12904,"count":0}],"isBlockCoverage":true},{"functionName":"buildApp","ranges":[{"startOffset":687,"endOffset":929,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":980,"endOffset":1070,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1105,"endOffset":1244,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1280,"endOffset":4295,"count":0}],"isBlockCoverage":false}]}]} \ No newline at end of file diff --git a/coverage/.tmp/coverage-7.json b/coverage/.tmp/coverage-7.json new file mode 100644 index 0000000..5d60161 --- /dev/null +++ b/coverage/.tmp/coverage-7.json @@ -0,0 +1 @@ +{"result":[{"scriptId":"375","url":"file:///home/samaro/cred/Creditra-Backend/src/db/validate-schema.test.ts","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":10521,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":13,"endOffset":10521,"count":1}],"isBlockCoverage":true},{"functionName":"createMockClient","ranges":[{"startOffset":446,"endOffset":664,"count":6}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":713,"endOffset":2573,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":787,"endOffset":1263,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1324,"endOffset":1731,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1792,"endOffset":2103,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":2184,"endOffset":2569,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":2625,"endOffset":3655,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":2709,"endOffset":3170,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":3236,"endOffset":3651,"count":1}],"isBlockCoverage":true}]},{"scriptId":"377","url":"file:///home/samaro/cred/Creditra-Backend/src/db/validate-schema.ts","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":3804,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":13,"endOffset":3804,"count":1}],"isBlockCoverage":true},{"functionName":"missingTables","ranges":[{"startOffset":307,"endOffset":795,"count":7}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":428,"endOffset":449,"count":30}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":685,"endOffset":704,"count":15}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":768,"endOffset":791,"count":30}],"isBlockCoverage":true},{"functionName":"get","ranges":[{"startOffset":897,"endOffset":926,"count":4}],"isBlockCoverage":true},{"functionName":"validateSchema","ranges":[{"startOffset":930,"endOffset":1112,"count":3},{"startOffset":1043,"endOffset":1110,"count":2}],"isBlockCoverage":true},{"functionName":"get","ranges":[{"startOffset":1215,"endOffset":1245,"count":3}],"isBlockCoverage":true}]},{"scriptId":"378","url":"file:///home/samaro/cred/Creditra-Backend/src/db/migrations.ts","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":9334,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":13,"endOffset":9334,"count":1}],"isBlockCoverage":true},{"functionName":"get","ranges":[{"startOffset":773,"endOffset":804,"count":5}],"isBlockCoverage":true},{"functionName":"ensureSchemaMigrations","ranges":[{"startOffset":808,"endOffset":904,"count":0}],"isBlockCoverage":false},{"functionName":"get","ranges":[{"startOffset":1015,"endOffset":1053,"count":0}],"isBlockCoverage":false},{"functionName":"listMigrationFiles","ranges":[{"startOffset":1057,"endOffset":1304,"count":0}],"isBlockCoverage":false},{"functionName":"get","ranges":[{"startOffset":1411,"endOffset":1445,"count":0}],"isBlockCoverage":false},{"functionName":"versionFromFilename","ranges":[{"startOffset":1449,"endOffset":1574,"count":0}],"isBlockCoverage":false},{"functionName":"get","ranges":[{"startOffset":1682,"endOffset":1717,"count":0}],"isBlockCoverage":false},{"functionName":"getAppliedVersions","ranges":[{"startOffset":1721,"endOffset":1974,"count":0}],"isBlockCoverage":false},{"functionName":"get","ranges":[{"startOffset":2081,"endOffset":2115,"count":0}],"isBlockCoverage":false},{"functionName":"applyMigration","ranges":[{"startOffset":2119,"endOffset":2548,"count":0}],"isBlockCoverage":false},{"functionName":"get","ranges":[{"startOffset":2651,"endOffset":2681,"count":0}],"isBlockCoverage":false},{"functionName":"runPendingMigrations","ranges":[{"startOffset":2685,"endOffset":3158,"count":0}],"isBlockCoverage":false},{"functionName":"get","ranges":[{"startOffset":3267,"endOffset":3303,"count":0}],"isBlockCoverage":false}]}]} \ No newline at end of file diff --git a/coverage/.tmp/coverage-8.json b/coverage/.tmp/coverage-8.json new file mode 100644 index 0000000..7832301 --- /dev/null +++ b/coverage/.tmp/coverage-8.json @@ -0,0 +1 @@ +{"result":[{"scriptId":"375","url":"file:///home/samaro/cred/Creditra-Backend/src/db/client.test.ts","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":2934,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":13,"endOffset":2934,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":488,"endOffset":1160,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":572,"endOffset":620,"count":2}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":657,"endOffset":726,"count":2},{"startOffset":690,"endOffset":722,"count":0}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":795,"endOffset":921,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":836,"endOffset":879,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":995,"endOffset":1156,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1071,"endOffset":1114,"count":1}],"isBlockCoverage":true}]},{"scriptId":"377","url":"file:///home/samaro/cred/Creditra-Backend/src/db/client.ts","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":2289,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":13,"endOffset":2289,"count":1}],"isBlockCoverage":true},{"functionName":"getConnection","ranges":[{"startOffset":373,"endOffset":587,"count":2},{"startOffset":506,"endOffset":586,"count":0}],"isBlockCoverage":true},{"functionName":"get","ranges":[{"startOffset":689,"endOffset":718,"count":2}],"isBlockCoverage":true}]}]} \ No newline at end of file diff --git a/coverage/lcov-report/base.css b/coverage/lcov-report/base.css deleted file mode 100644 index f418035..0000000 --- a/coverage/lcov-report/base.css +++ /dev/null @@ -1,224 +0,0 @@ -body, html { - margin:0; padding: 0; - height: 100%; -} -body { - font-family: Helvetica Neue, Helvetica, Arial; - font-size: 14px; - color:#333; -} -.small { font-size: 12px; } -*, *:after, *:before { - -webkit-box-sizing:border-box; - -moz-box-sizing:border-box; - box-sizing:border-box; - } -h1 { font-size: 20px; margin: 0;} -h2 { font-size: 14px; } -pre { - font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; - margin: 0; - padding: 0; - -moz-tab-size: 2; - -o-tab-size: 2; - tab-size: 2; -} -a { color:#0074D9; text-decoration:none; } -a:hover { text-decoration:underline; } -.strong { font-weight: bold; } -.space-top1 { padding: 10px 0 0 0; } -.pad2y { padding: 20px 0; } -.pad1y { padding: 10px 0; } -.pad2x { padding: 0 20px; } -.pad2 { padding: 20px; } -.pad1 { padding: 10px; } -.space-left2 { padding-left:55px; } -.space-right2 { padding-right:20px; } -.center { text-align:center; } -.clearfix { display:block; } -.clearfix:after { - content:''; - display:block; - height:0; - clear:both; - visibility:hidden; - } -.fl { float: left; } -@media only screen and (max-width:640px) { - .col3 { width:100%; max-width:100%; } - .hide-mobile { display:none!important; } -} - -.quiet { - color: #7f7f7f; - color: rgba(0,0,0,0.5); -} -.quiet a { opacity: 0.7; } - -.fraction { - font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; - font-size: 10px; - color: #555; - background: #E8E8E8; - padding: 4px 5px; - border-radius: 3px; - vertical-align: middle; -} - -div.path a:link, div.path a:visited { color: #333; } -table.coverage { - border-collapse: collapse; - margin: 10px 0 0 0; - padding: 0; -} - -table.coverage td { - margin: 0; - padding: 0; - vertical-align: top; -} -table.coverage td.line-count { - text-align: right; - padding: 0 5px 0 20px; -} -table.coverage td.line-coverage { - text-align: right; - padding-right: 10px; - min-width:20px; -} - -table.coverage td span.cline-any { - display: inline-block; - padding: 0 5px; - width: 100%; -} -.missing-if-branch { - display: inline-block; - margin-right: 5px; - border-radius: 3px; - position: relative; - padding: 0 4px; - background: #333; - color: yellow; -} - -.skip-if-branch { - display: none; - margin-right: 10px; - position: relative; - padding: 0 4px; - background: #ccc; - color: white; -} -.missing-if-branch .typ, .skip-if-branch .typ { - color: inherit !important; -} -.coverage-summary { - border-collapse: collapse; - width: 100%; -} -.coverage-summary tr { border-bottom: 1px solid #bbb; } -.keyline-all { border: 1px solid #ddd; } -.coverage-summary td, .coverage-summary th { padding: 10px; } -.coverage-summary tbody { border: 1px solid #bbb; } -.coverage-summary td { border-right: 1px solid #bbb; } -.coverage-summary td:last-child { border-right: none; } -.coverage-summary th { - text-align: left; - font-weight: normal; - white-space: nowrap; -} -.coverage-summary th.file { border-right: none !important; } -.coverage-summary th.pct { } -.coverage-summary th.pic, -.coverage-summary th.abs, -.coverage-summary td.pct, -.coverage-summary td.abs { text-align: right; } -.coverage-summary td.file { white-space: nowrap; } -.coverage-summary td.pic { min-width: 120px !important; } -.coverage-summary tfoot td { } - -.coverage-summary .sorter { - height: 10px; - width: 7px; - display: inline-block; - margin-left: 0.5em; - background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; -} -.coverage-summary .sorted .sorter { - background-position: 0 -20px; -} -.coverage-summary .sorted-desc .sorter { - background-position: 0 -10px; -} -.status-line { height: 10px; } -/* yellow */ -.cbranch-no { background: yellow !important; color: #111; } -/* dark red */ -.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } -.low .chart { border:1px solid #C21F39 } -.highlighted, -.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ - background: #C21F39 !important; -} -/* medium red */ -.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } -/* light red */ -.low, .cline-no { background:#FCE1E5 } -/* light green */ -.high, .cline-yes { background:rgb(230,245,208) } -/* medium green */ -.cstat-yes { background:rgb(161,215,106) } -/* dark green */ -.status-line.high, .high .cover-fill { background:rgb(77,146,33) } -.high .chart { border:1px solid rgb(77,146,33) } -/* dark yellow (gold) */ -.status-line.medium, .medium .cover-fill { background: #f9cd0b; } -.medium .chart { border:1px solid #f9cd0b; } -/* light yellow */ -.medium { background: #fff4c2; } - -.cstat-skip { background: #ddd; color: #111; } -.fstat-skip { background: #ddd; color: #111 !important; } -.cbranch-skip { background: #ddd !important; color: #111; } - -span.cline-neutral { background: #eaeaea; } - -.coverage-summary td.empty { - opacity: .5; - padding-top: 4px; - padding-bottom: 4px; - line-height: 1; - color: #888; -} - -.cover-fill, .cover-empty { - display:inline-block; - height: 12px; -} -.chart { - line-height: 0; -} -.cover-empty { - background: white; -} -.cover-full { - border-right: none !important; -} -pre.prettyprint { - border: none !important; - padding: 0 !important; - margin: 0 !important; -} -.com { color: #999 !important; } -.ignore-none { color: #999; font-weight: normal; } - -.wrapper { - min-height: 100%; - height: auto !important; - height: 100%; - margin: 0 auto -48px; -} -.footer, .push { - height: 48px; -} diff --git a/coverage/lcov-report/block-navigation.js b/coverage/lcov-report/block-navigation.js deleted file mode 100644 index 530d1ed..0000000 --- a/coverage/lcov-report/block-navigation.js +++ /dev/null @@ -1,87 +0,0 @@ -/* eslint-disable */ -var jumpToCode = (function init() { - // Classes of code we would like to highlight in the file view - var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; - - // Elements to highlight in the file listing view - var fileListingElements = ['td.pct.low']; - - // We don't want to select elements that are direct descendants of another match - var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` - - // Selector that finds elements on the page to which we can jump - var selector = - fileListingElements.join(', ') + - ', ' + - notSelector + - missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` - - // The NodeList of matching elements - var missingCoverageElements = document.querySelectorAll(selector); - - var currentIndex; - - function toggleClass(index) { - missingCoverageElements - .item(currentIndex) - .classList.remove('highlighted'); - missingCoverageElements.item(index).classList.add('highlighted'); - } - - function makeCurrent(index) { - toggleClass(index); - currentIndex = index; - missingCoverageElements.item(index).scrollIntoView({ - behavior: 'smooth', - block: 'center', - inline: 'center' - }); - } - - function goToPrevious() { - var nextIndex = 0; - if (typeof currentIndex !== 'number' || currentIndex === 0) { - nextIndex = missingCoverageElements.length - 1; - } else if (missingCoverageElements.length > 1) { - nextIndex = currentIndex - 1; - } - - makeCurrent(nextIndex); - } - - function goToNext() { - var nextIndex = 0; - - if ( - typeof currentIndex === 'number' && - currentIndex < missingCoverageElements.length - 1 - ) { - nextIndex = currentIndex + 1; - } - - makeCurrent(nextIndex); - } - - return function jump(event) { - if ( - document.getElementById('fileSearch') === document.activeElement && - document.activeElement != null - ) { - // if we're currently focused on the search input, we don't want to navigate - return; - } - - switch (event.which) { - case 78: // n - case 74: // j - goToNext(); - break; - case 66: // b - case 75: // k - case 80: // p - goToPrevious(); - break; - } - }; -})(); -window.addEventListener('keydown', jumpToCode); diff --git a/coverage/lcov-report/favicon.png b/coverage/lcov-report/favicon.png deleted file mode 100644 index c1525b8..0000000 Binary files a/coverage/lcov-report/favicon.png and /dev/null differ diff --git a/coverage/lcov-report/index.html b/coverage/lcov-report/index.html deleted file mode 100644 index 1915251..0000000 --- a/coverage/lcov-report/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - -
-- Press n or j to go to the next uncovered block, b, p or k for the previous block. -
- -| File | -- | Statements | -- | Branches | -- | Functions | -- | Lines | -- |
|---|---|---|---|---|---|---|---|---|---|
| migrations.ts | -
-
- |
- 100% | -98/98 | -100% | -12/12 | -100% | -6/6 | -100% | -98/98 | -
| validate-schema.ts | -
-
- |
- 100% | -34/34 | -100% | -6/6 | -100% | -2/2 | -100% | -34/34 | -
- Press n or j to go to the next uncovered block, b, p or k for the previous block. -
- -| 1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 | 1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -5x -5x -5x -1x -1x -1x -1x -3x -3x -3x -3x -3x -3x -3x -3x -1x -1x -1x -1x -1x -6x -5x -5x -1x -1x -1x -1x -4x -4x -4x -4x -4x -4x -4x -4x -1x -1x -1x -1x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -1x -1x -1x -1x -1x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -1x -1x -1x -1x -2x -2x - | import { readdir, readFile } from 'fs/promises';
-import { join } from 'path';
-import type { DbClient } from './client.js';
-
-const SCHEMA_MIGRATIONS_TABLE = `
-CREATE TABLE IF NOT EXISTS schema_migrations (
- version TEXT PRIMARY KEY,
- applied_at TIMESTAMPTZ NOT NULL DEFAULT now()
-);
-`;
-
-/** Expected core tables that must exist after initial schema. */
-export const EXPECTED_TABLES = [
- 'borrowers',
- 'credit_lines',
- 'risk_evaluations',
- 'transactions',
- 'events',
-] as const;
-
-/**
- * Ensure schema_migrations table exists (for first-run or standalone migration).
- */
-export async function ensureSchemaMigrations(client: DbClient): Promise<void> {
- await client.query(SCHEMA_MIGRATIONS_TABLE);
-}
-
-/**
- * Return sorted list of migration filenames (e.g. 001_initial_schema.sql) in the given directory.
- */
-export async function listMigrationFiles(dir: string): Promise<string[]> {
- const entries = await readdir(dir, { withFileTypes: true });
- const files = entries
- .filter((e) => e.isFile() && e.name.endsWith('.sql'))
- .map((e) => e.name)
- .sort();
- return files;
-}
-
-/**
- * Extract version string from migration filename (e.g. 001_initial_schema.sql -> 001_initial_schema).
- */
-export function versionFromFilename(filename: string): string {
- if (!filename.endsWith('.sql')) return filename;
- return filename.slice(0, -4);
-}
-
-/**
- * Get applied migration versions from schema_migrations.
- */
-export async function getAppliedVersions(client: DbClient): Promise<string[]> {
- await ensureSchemaMigrations(client);
- const result = await client.query(
- 'SELECT version FROM schema_migrations ORDER BY version'
- );
- const rows = result.rows as { version: string }[];
- return rows.map((r) => r.version);
-}
-
-/**
- * Apply a single migration file (run its SQL and record version).
- */
-export async function applyMigration(
- client: DbClient,
- migrationsDir: string,
- filename: string
-): Promise<void> {
- const path = join(migrationsDir, filename);
- const sql = await readFile(path, 'utf-8');
- await client.query(sql);
- const version = versionFromFilename(filename);
- await client.query(
- 'INSERT INTO schema_migrations (version, applied_at) VALUES ($1, now()) ON CONFLICT (version) DO NOTHING',
- [version]
- );
-}
-
-/**
- * Run all pending migrations in the given directory.
- * Uses process.cwd() if migrationsDir is not absolute to resolve relative to cwd.
- */
-export async function runPendingMigrations(
- client: DbClient,
- migrationsDir: string
-): Promise<string[]> {
- const applied = await getAppliedVersions(client);
- const files = await listMigrationFiles(migrationsDir);
- const appliedSet = new Set(applied);
- const run: string[] = [];
- for (const file of files) {
- const version = versionFromFilename(file);
- if (appliedSet.has(version)) continue;
- await applyMigration(client, migrationsDir, file);
- run.push(version);
- appliedSet.add(version);
- }
- return run;
-}
- |