Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bugfix] fix applications results #956

Merged
merged 2 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/api/src/controllers/v2/microcredit/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class MicroCreditController {
}

this.microCreditService
.postDocs(req.user.userId, req.body)
.postDocs(req.user.userId, req.body.applicationId, req.body.docs)
.then(r => standardResponse(res, 201, true, r))
.catch(e => standardResponse(res, 400, false, '', { error: e }));
};
Expand Down
28 changes: 18 additions & 10 deletions packages/api/src/routes/v2/microcredit/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,19 +57,26 @@ export default (route: Router): void => {
* - "microcredit"
* summary: "Add microcredit related docs to a user"
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: array
* items:
* type: object
* properties:
* filepath:
* type: string
* example: some/path/to/file.pdf
* category:
* type: number
* example: 1
* type: object
* properties:
* applicationId:
* type: number
* required: true
* docs:
* type: array
* items:
* type: object
* properties:
* filepath:
* type: string
* example: some/path/to/file.pdf
* category:
* type: number
* example: 1
* responses:
* "200":
* description: "Success"
Expand All @@ -92,6 +99,7 @@ export default (route: Router): void => {
* summary: "Update microcredit applications"
* description: "Status can be 0: pending, 1: submitted, 2: in-review, 3: requested-changes, 4: interview, 5: approved, 6: rejected"
* requestBody:
* required: true
* content:
* application/json:
* schema:
Expand Down
33 changes: 20 additions & 13 deletions packages/api/src/validators/microcredit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,15 @@ interface GetBorrowerRequestSchema extends ValidatedRequestSchema {
// I wish this comes true https://github.com/hapijs/joi/issues/2864#issuecomment-1322736004

// This should match Joi validations
type PostDocsRequestType = [
{
filepath: string;
category: number;
}
];
type PostDocsRequestType = {
applicationId: number;
docs: [
{
filepath: string;
category: number;
}
];
};
type PutApplicationsRequestType = [
{
applicationId: number;
Expand All @@ -142,13 +145,17 @@ const preSignerUrlFromAWSValidator = validator.query(queryPreSignerUrlFromAWSSch
const queryGetBorrowerValidator = validator.query(queryGetBorrowerSchema);
const postDocsValidator = celebrate({
body: defaultSchema
.array<PostDocsRequestType>()
.items(
Joi.object({
filepath: Joi.string().required(),
category: Joi.number().required()
}).required()
)
.object<PostDocsRequestType>({
applicationId: Joi.number().required(),
docs: Joi.array()
.items(
Joi.object({
filepath: Joi.string().required(),
category: Joi.number().required()
})
)
.required()
})
.required()
});
const putApplicationsValidator = celebrate({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ module.exports = {
type: Sequelize.INTEGER,
allowNull: false
},
applicationId: {
type: Sequelize.INTEGER,
allowNull: false
},
category: {
allowNull: false,
type: Sequelize.INTEGER
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use strict';
/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.addColumn('microcredit_docs', 'applicationId', {
type: Sequelize.INTEGER,
allowNull: true
});

await queryInterface.sequelize.query(`
UPDATE microcredit_docs
SET "applicationId" = (
SELECT id
FROM microcredit_applications
WHERE microcredit_applications."userId" = microcredit_docs."userId"
ORDER BY "createdAt" DESC
LIMIT 1
)
WHERE "applicationId" IS NULL
`);

await queryInterface.sequelize.query(`
DELETE from microcredit_docs
WHERE "applicationId" IS NULL
`);

await queryInterface.changeColumn('microcredit_docs', 'applicationId', {
type: Sequelize.INTEGER,
allowNull: false
});
},
async down(queryInterface, Sequelize) {
//
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';
/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.addColumn('microcredit_applications', 'signedOn', {
allowNull: true,
type: Sequelize.DATE
});

await queryInterface.addColumn('microcredit_applications', 'claimedOn', {
allowNull: true,
type: Sequelize.DATE
});
},
async down(queryInterface, Sequelize) {
//
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict';
/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up(queryInterface, Sequelize) {
// update microcredit_applications setting signedOn to each user, based on when the user uploaded a doc to microcredit_docs with category 1
await queryInterface.sequelize.query(`
UPDATE microcredit_applications
SET "signedOn" = (
SELECT "createdAt"
FROM microcredit_docs
WHERE microcredit_docs."userId" = microcredit_applications."userId"
AND microcredit_docs."category" = 1
ORDER BY "createdAt" DESC
LIMIT 1
)
`);

// update microcredit_applications setting claimedOn to each user, based on when the user claimed the loan, getting that info from "claimed" on subgraph_microcredit_borrowers
await queryInterface.sequelize.query(`
UPDATE microcredit_applications
SET "claimedOn" = (
SELECT to_timestamp("claimed")::timestamptz
FROM subgraph_microcredit_borrowers
WHERE subgraph_microcredit_borrowers."userId" = microcredit_applications."userId"
ORDER BY "createdAt" DESC
LIMIT 1
)
`);
},
async down(queryInterface, Sequelize) {
//
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use strict';
/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.sequelize.query(`
DELETE FROM microcredit_docs AS t1
WHERE id NOT IN (
SELECT id
FROM microcredit_docs AS t2
WHERE t1."applicationId" = t2."applicationId"
AND t1.category = t2.category
AND t1.id < t2.id
);
`);
},
async down(queryInterface, Sequelize) {
//
}
};
2 changes: 1 addition & 1 deletion packages/core/src/database/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ export default function initModels(sequelize: Sequelize): void {
initializeLearnAndEarnUserData(sequelize);

// MicroCredit
initializeMicroCreditDocs(sequelize);
initializeMicroCreditApplication(sequelize);
initializeMicroCreditDocs(sequelize);
initializeMicroCreditBorrowers(sequelize);
initializeMicroCreditBorrowersHuma(sequelize);
initializeMicroCreditNote(sequelize);
Expand Down
14 changes: 14 additions & 0 deletions packages/core/src/database/models/microCredit/applications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { DataTypes, Model, Sequelize } from 'sequelize';
import { AppUserModel } from '../app/appUser';
import { DbModels } from '../../../database/db';
import { MicroCreditApplication, MicroCreditApplicationCreation } from '../../../interfaces/microCredit/applications';
import { MicroCreditDocsModel } from './docs';
import { SubgraphMicroCreditBorrowersModel } from './subgraphBorrowers';

export class MicroCreditApplicationModel extends Model<MicroCreditApplication, MicroCreditApplicationCreation> {
public id!: number;
Expand All @@ -14,12 +16,16 @@ export class MicroCreditApplicationModel extends Model<MicroCreditApplication, M
public period!: number;
public status!: number;
public decisionOn!: Date;
public signedOn!: Date;
public claimedOn!: Date;

// timestamps!
public readonly createdAt!: Date;
public readonly updatedAt!: Date;

public readonly user?: AppUserModel;
public readonly docs?: MicroCreditDocsModel[];
public readonly borrower?: SubgraphMicroCreditBorrowersModel;
}

export function initializeMicroCreditApplication(sequelize: Sequelize): typeof MicroCreditApplicationModel {
Expand Down Expand Up @@ -68,6 +74,14 @@ export function initializeMicroCreditApplication(sequelize: Sequelize): typeof M
allowNull: true,
type: DataTypes.DATE
},
signedOn: {
allowNull: true,
type: DataTypes.DATE
},
claimedOn: {
allowNull: true,
type: DataTypes.DATE
},
createdAt: {
type: DataTypes.DATE,
allowNull: false
Expand Down
21 changes: 19 additions & 2 deletions packages/core/src/database/models/microCredit/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { MicroCreditDocs, MicroCreditDocsCreationAttributes } from '../../../int
export class MicroCreditDocsModel extends Model<MicroCreditDocs, MicroCreditDocsCreationAttributes> {
public id!: number;
public userId!: number;
public applicationId!: number;
public category!: number;
public filepath!: string;

Expand All @@ -15,7 +16,7 @@ export class MicroCreditDocsModel extends Model<MicroCreditDocs, MicroCreditDocs
}

export function initializeMicroCreditDocs(sequelize: Sequelize): typeof MicroCreditDocsModel {
const { appUser } = sequelize.models as DbModels;
const { appUser, microCreditApplications } = sequelize.models as DbModels;
MicroCreditDocsModel.init(
{
id: {
Expand All @@ -32,6 +33,15 @@ export function initializeMicroCreditDocs(sequelize: Sequelize): typeof MicroCre
onDelete: 'CASCADE',
allowNull: false
},
applicationId: {
type: DataTypes.INTEGER,
references: {
model: microCreditApplications,
key: 'id'
},
onDelete: 'CASCADE',
allowNull: false
},
category: {
type: DataTypes.INTEGER,
allowNull: false
Expand All @@ -52,7 +62,14 @@ export function initializeMicroCreditDocs(sequelize: Sequelize): typeof MicroCre
{
tableName: 'microcredit_docs',
modelName: 'microCreditDocs',
sequelize
sequelize,
// ensure that applicationId + category is unique
indexes: [
{
unique: true,
fields: ['applicationId', 'category']
}
]
}
);
return MicroCreditDocsModel;
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/interfaces/microCredit/applications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export interface MicroCreditApplication {
period: number;
status: number;
decisionOn: Date;
signedOn: Date;
claimedOn: Date;

// timestamps
createdAt: Date;
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/interfaces/microCredit/docs.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export interface MicroCreditDocs {
id: number;
userId: number;
applicationId: number;
category: number;
filepath: string;

Expand All @@ -11,6 +12,7 @@ export interface MicroCreditDocs {

export interface MicroCreditDocsCreationAttributes {
userId: number;
applicationId: number;
category: number;
filepath: string;
}
Loading
Loading