collactionteam / collaction_api Goto Github PK
View Code? Open in Web Editor NEWThe API powering the Collaction Client Applications
License: GNU Affero General Public License v3.0
The API powering the Collaction Client Applications
License: GNU Affero General Public License v3.0
We will require an endpoint to fetch posts given a Thread ID.
The endpoint should be paginated.
The endpoint should be owned by the Posts controller, an idea of how the endpoint could look:
v1/posts/:tid/
where tid is Thread ID
Implement the required Query if it doesn't already exist, eg. FetchPostsByThread
. See list-crowdactions.query.ts
for reference on how to implement pagination.
I've started off with adding unit tests to the profile section of the app. So far I'm working on adding tests to the ProfileController
and ProfileService
files but am having trouble getting the tests to work with NestJS.
Basing the tests off this article so far.
Branch where the work is being done is https://github.com/CollActionteam/collaction_api/tree/feat/add-unit-tests
Description:
For the badges feature, we will refactor commitment options, which currently is just a hardcoded enumerator.
This ticket is responsible for creating the Entity and Interface,
src/domain
create a new folder commitmentoption
entity
and interface
folders, as well as an index.ts
file that will barrel the contents of these two folders.The entity and interface should be created according to this:
CommitmentOption {
id: string; // Mongoose ID
label: string;
description: string;
points: number;
blocks: CommitmentOption[];
category: CrowdActionCategoryEnum; // Eg. food, sustainability,
}
All fields must be readonly, there are no optional fields.
Note: Remember to create index.ts files inside the entity and interface folder, and export the commitmentoption.entity.ts
and the commitmentoption.interface.ts
files so it can be imported by @domain/commitmentoption
Need to increase coverage for the SendFormCommand. This should be a good first issue. I don't believe it should be too tricky.
When requesting a non-existing profile, an HTTP status code 404 should be returned (not 500).
Description:
When a crowdaction is created, depending on the type of the crowdaction, an automatic thread needs to be created in the corresponding forum (Forum linekd to CrowdActionType).
If no forum exists with that CrowdActionType, then the CrowdAction will not be linked to a thread.
Additionally:
Make neccessary changes to CrowdAction to add threadId
which is an optional (nullable) field.
Requirements:
Mapping:
Thread Subject => CrowdAction Title
Thread Author => (We will create a bot user, yet to figure out the details!)
Thread Prefix => (Maybe we can have a Prefix for each CrowdActionType - Would look nice on the website at the end)
Thread Message:
[img]<CrowdAction Banner Image>[/img]
**<CrowdAction Title>**
Join ends at: <CrowdAction Join End At>
Starts at: <CrowdAction Start At>
Ends at <CrowdAction End At>
**Description:**
<CrowdAction Description>
Description
In the UploadProfileImageCommand
we currently have no validations in place.
Don't spend too much time on this task, if some validations take too long, then simply skip them.
Validations:
Instead of using an AWS lambda to send emails to the CollAction email account we can instead store this information in a table. This data can then be fetched to display the emails and not require us to send the emails to ourselves
Need to add unit tests for the AuthService. This may be tricky but would be a good place to start for understanding how we authenticate users.
Regarding /v1/crowdactions/slug/{slug}
endpoint:
When requesting a crowdaction by a slug that doesn't exist, there is a mismatch in the response between the Status
of the response: 500 and the statusCode
of the response body "statusCode": 400
could be confusing for the client. Would be better if both are 404 Not Found.
Regarding /v1/crowdactions/{id}
endpoint:
When requesting a crowdaction by an id that doesn't exist, the Status
of the response is 500. Would be more convenient if the response is 404 Not Found.
Description:
We need to create a persistence for the new CommitmentOption entity.
Inside src/infrastructure/mongo/persistence
create a new file commitmentoption.persistence.ts
.
Export a class decorated with @Schema({ _id: false, versionKey: false })
named CommitmentOptionPersistence
.
See crowdaction.persistence.ts
for a similar setup.
Must export the persistence class, the CommitmentOptionSchema, and the CommitmentOptionDocument.
For the followers feature in the future the backend needs to be able to use a phone number from a users contacts to fetch userIds. We store the users phone number with Firebase Authentication. It seems the userId across the backend and Firebase is the same so assuming we can fetch users from Firebase using their phone number it should then be simple to do the rest in the backend with the findUserByIdOrFail
function.
Description:
As we will add posts to a specific Thread from the Mobile Application, we will need to expose an authorized endpoint.
More info later!
We need badges to store the information of the crowdaction that uses it. The information it needs to store is the crowdactions title
and id
.
We also need to add a new field called icon
that is a type string. This will be used so user can upload their own images for badges. The field will be optional and we will default to a hardcoded image on the app side if no icon is provided.
Make the diamond threshold value customizable and keep hardcoded values for the other tiers. We can pass this in through the crowdaction in the delegate-badges command. This means we will need to add a diamond threshold to the crowdaction persistence too since the badges are delegated by the CRON and not a call.
We could do this by adding a new BadgeConfig
object inside the crowdactions. For now this would only store the diamond threshold value but we may add new things to it in the future.
Description:
Before we can start creating the endpoints and refactor the old commitment options, we need to setup the repository.
First, we must create the abstract interface that the repository will implement.
Inside src/domain/commitmentoption/interface
create commitmentoption-repository.interface.ts
.
The file will export:
Omit<ICommitmentOption, 'id' | 'createdAt' | 'updatedAt'>
Partial<ICommitmentOption>
Partial<Pick<ICommitmentOption, 'id' | 'category'>>
For the new ICommitmentOptionRepository
, implement IRepository
using the above types:
export abstract class ICommitmentOptionRepository implements IRepository<CommitmentOption, CreateCommitmentOption, PatchCommitmentOption, QueryCommitmentOption>
Inside src/infrastructure/mongo/repository
create commitmentoption.repository.ts
.
The repository must be an @Injectable()
.
In the constructor, inject the CommitmentOptionPersistence.name
created in #10, like this:
@Injectable()
export class CommitmentOptionRepository implements ICommitmentOptionRepository {
constructor(@InjectModel(CommitmentOptionPersistence.name) private readonly documentModel: Model<CommitmentOptionDocument>) {}
For the repository method implementations, reference src/infrastructure/mongo/repository/crowdaction.repository.ts
Blocked by: #10 !
This task is two-part, one is implementing the endpoint, and the other is implementing the command to create a Post.
The endpoint should be authenticated (FirebaseGuard).
The command should take these arguments:
"RE: ${thread.subject"}
)Validation before creating the post in chronological order:
We will need an endpoint to create threads, the endpoint must require authentication.
The endpoint will take (and of course have the user from the token):
The task also includes creating a command CreateThreadCommand
, that will require these validations:
The command should take the information received through the endpoint as arguments, and also require a User!
We will add support for creating polls etc. at a later point.
Description:
We need to configure Task Scheduling in our project.
Setup Task Scheduler from NestJS, create a Task that every hour print:
[TaskScheduler] Task Scheduler is running
We need to increase our coverage for this class. Please keep in mind that the Crons will need to be stopped once a test is done.
Initial comment:
We're going to decouple CrowdAction Type from CommitmentOptions. Meaning a CrowdAction will no longer inherit CommitmentOptions by the CrowdAction Type.
Instead when we create CommitmentOptions, they will still have a Type, but they will also have an additional List of Tags. When creating a CrowdAction, UI wise, we will allow to search and select commitmentoptions by these tags.
That means a CrowdAction will have to be created with commitmentOptions: [string] like previously done, where it's a list of ids of the desired commitmentoptions.
This means we will also have to change/add this functionality (and the above):
Link to Slack thread where discussion took place: https://collaction-team.slack.com/archives/C03GTBZBYTB/p1670786658224969
Currently on server startup we need to schedule all crowdactions to run their CRONs so that crowdaction start and end at the correct time.
The work for scheduling crowdactions has already been done in SchedulerService
. We simply need to call scheduleTasks
from this new startup Service and the job should be done.
We should be able to use Lifecycle events to do this code. Based on a quick look using onModuleInit
should be enough
https://docs.nestjs.com/fundamentals/lifecycle-events
If we can reuse this startup code for the future it could be useful too.
We need an endpoint to fetch threads for a specific forum, the endpoint should be paginated and should have or use a Query, eg. list-threads.query.ts
.
See list-crowdactions.query.ts
to reference how to add pagination.
The endpoint should exist in the Thread Controller, and the endpoint could be:
v1/threads/:fid
The contact controller so far only has one endpoint. The send form command. We should add an option to fetch a contact based on it's id. This will require adding a ContactService
and fetching the contact using the ContactRepository
findOne query.
There are plenty of examples from other controllers too if you need to see them.
After adding the endpoint make sure to update the SendFormCommand unit test.
TBD
Update all GET requests that return crowdactions so they return them in a sorted order based on the endAt
value. The crowdactions list will be returned in a DESC order.
We will use the board also to power the "comments" feature in the Mobile Application and link them together.
The business logic in itself will go according to which Forum is linked to which CrowdAction Type.
Requirements:
The command should function like this procedurally:
For the thread creation:
Note: This task is dependant on #94 - And we still have to define a clear method of authoring threads from one specific author (eg. CollAction Bot).
Add a code coverage check to the CI/CD and decide on a value that means the build should fail.
Files that need to have their coverage increased
FindCrowdActionByIdQuery
ListCrowdActionsQuery
GetParticipationForCrowdactionQuery
ListCrowdActionsForUserQuery
Description:
It seems that after the refactor, the constructor which initializes the S3Client was removed, thus making it impossible to upload to S3.
Another issue was, that due to S3ClientRepository not being provided properly, configService
is undefined.
Description:
To be able to perform CRUD operations on the new CommitmentOption, we will set up a controller. For now, the controller will just have one endpoint that will return Hello World.
Inside src/api/rest
create a new folder commitmentoptions
and inside it create v1/controller/
folders.
In the controller
folder create commitmentoption.controller.ts
and index.ts
Export the class CommitmentOptionController
which is decorated with @Controller('v1/commitmentoptions')
and @ApiTags('CommitmentOption')
Create a Get endpoint that returns Hello World!
We want to have the same scaffold of the board on both development and production, to not have to set everything up manually, we're going to write one or multiple migration that will insert the proper documents with the correct inheritance.
Migration(s):
... TBD
Currently we use a CRON to check every hour if a crowdaction is finished. If it is we then award the badges to all the participants of that crowdaction. Instead of this we should see if it's possible to create a custom CRON that will be triggered when the end date of the crowdaction is less than the current date. This way the badges are awarded the second the crowdaction is finished.
The NestJS documentation on task scheduling should be helpful for this: https://docs.nestjs.com/techniques/task-scheduling
Description
Inside the ProfileController, the @Put() updateProfile
method takes UpdateProfileDto
which contains phone
, we do not allow users to update their phone numbers, as it's part of Firebase Authentication. Thus we have to remove this and make sure it's not used by any other resource or controller.
We also currently return Identifiable
and in the @ApiResponse
decorator we declare the type as IdentifiableResponse
, instead we should fetch and return the new and updated Profile.
The fetching of the Profile should be done in the UpdateProfileCommand
and the command should return the updated Profile.
Use the ProfileResponseDto as the response from thic ticket: #1
Acceptance Criteria
Currently we use the CommitmentIconEnum
to choose an image that out commitments will display. We will be replacing this with a string so users can provide their own images for commitments.
We will also be deleting the CommitmentIconEnum
.
I believe this will also require a migration for all existing commitments so we can remove the enum and replace it with a string url pointing to the correct image.
Currently to award a badge to participants we use a 3 for loop nested structure. This is bad for performance. We should find some way to improve this so it won't take as long for badges to be awarded.
We currently use the word increment to describe a feature that both increases and decreases the value of the number of crowdactions. We should replace this with better naming.
To make testing the id queries easier we will remove MongoMemoryServer and replace it with static responses with an expected outcome
Description
As I have implemented AWS S3 in the project, and we use this to upload images, it needs to be defined in the readme what endpoints won't work without them. And how to get the secrets if needed.
Description
In preparation for the board, we will create PRs that will cover all the needed entities, interfaces, and enumerations for the project.
This includes:
Required Models:
Required Enums:
PRs can be made in bunches or in one big PR, reminder of abstraction location:
infrastructure/mongo/persistence/<entity>.persistence.ts
infrastructure/<entity>/dto/<entity>.dto.ts
domain/<entity>/entity/<entity>.entity.ts
domain/<entity>/enum/<enum>.enum.ts
domain/<entity>/interface/<interface>.interface.ts
Naming conventions can be found in Confluence.
Integrations tests should verify the entire flow from an endpoint. Thus, we should have an integration test for each of the following components:
Description
Currently, we use the ProfileDto
in the @ApiResponse
decorator inside the ProfileController, this is not relevant. This DTO is used for incoming requests only, we should instead implement a ProfileResponseDto
instead.
For Swagger to show this response, the fields must be decorated with proper @ApiProperty
decorators.
Acceptance Criteria
@ApiResponse
decorator for getProfile
and getAuthedProfile
use ProfileResponseDto so that it correctly displays the response in Swagger UISample Response
{
"id": "628cdea92e19fd912f0d520e",
"userId": "O9pbPDY3s5e5XwzgwKZtZTDPvLS2",
"phone": "+4530249838",
"location": {
"code": "NL",
"name": "Netherlands"
},
"firstName": "Mathias",
"lastName": "M",
"bio": "I am a cool guy aye"
}
Current Response Example Value
{
"phone": "+31612345678",
"country": "string",
"firstName": "John",
"lastName": "Doe",
"bio": "I am a cool guy"
}
Precondition: User participates in a CrowdAction
When user clicks on participant list, it should see itself at the top of the list to make clear he/she participates in the CrowdAction, regardless of the order of the list (whether it's sorted alphabetically, on date, or anything else).
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.