Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR implements a complete review campaign system that allows event organizers to create custom review forms and collect feedback from attendees. The implementation includes GraphQL resolvers, TypeORM models, input types, and database migrations for the entire review workflow.
- Complete review campaign functionality with CRUD operations for campaigns, questions, and reviews
- Support for multiple question types (text, range, dropdown) with configurable options
- Authentication middleware and proper context typing for GraphQL operations
Reviewed Changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/types/MyContext.ts | Defines GraphQL context interface with Express request/response and session |
| src/resolvers/index.ts | Exports the new ReviewResolver |
| src/resolvers/ReviewResolver.ts | Main resolver with all CRUD operations for review campaigns, questions, and reviews |
| src/models/types/reviews/ | Input type definitions for GraphQL mutations and queries |
| src/models/reviews/ | TypeORM entity models for the review system database schema |
| src/migration/1700000000000-CreateReviewTables.ts | Database migration to create all review-related tables |
| src/middleware/isAuth.ts | Authentication middleware for protected mutations |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
src/resolvers/ReviewResolver.ts
Outdated
| // Review Campaign Mutations | ||
| @Mutation(() => CreateReviewCampaignPayload) | ||
| @UseMiddleware(isAuth) | ||
| async createReviewCampaign(@Arg("input") input: CreateReviewCampaignInput, @Ctx() { req }: any) { |
There was a problem hiding this comment.
The context parameter should be properly typed using the MyContext interface instead of any to maintain type safety.
src/models/reviews/ReviewAnswer.ts
Outdated
|
|
||
| @CreateDateColumn() | ||
| @Field() | ||
| createAt: Date; |
There was a problem hiding this comment.
Property name should be createdAt to be consistent with other entities and standard naming conventions.
| createAt: Date; | |
| createdAt: Date; |
| isNullable: true | ||
| }, | ||
| { | ||
| name: "createAt", |
There was a problem hiding this comment.
Column name should be createdAt to match the entity definition and standard naming conventions.
| name: "createAt", | |
| name: "createdAt", |
src/models/reviews/README.md
Outdated
| **Fields:** | ||
|
|
||
| - `id`: Unique identifier (UUID) | ||
| - `name`: Campaign name |
There was a problem hiding this comment.
The documentation refers to a name field, but the actual entity uses title. This should be corrected to match the implementation.
| - `name`: Campaign name | |
| - `title`: Campaign title |
src/models/reviews/README.md
Outdated
| - `textAnswer`: Text answer (for text questions) | ||
| - `rangeAnswer`: Numeric answer (for range questions) | ||
| - `dropDownAnswer`: Selected dropdown option (for dropdown questions) | ||
| - `createAt`: Creation timestamp |
There was a problem hiding this comment.
Field name should be createdAt to match the entity definition and standard naming conventions.
| - `createAt`: Creation timestamp | |
| - `createdAt`: Creation timestamp |
src/models/reviews/README.md
Outdated
| const campaign = await ReviewCampaign.create({ | ||
| name: "Event Feedback 2024", |
There was a problem hiding this comment.
The example code uses name property, but the actual entity uses title. This should be corrected to match the implementation.
There was a problem hiding this comment.
I see what your trying to do with this isAuth, but this implementation won't work, for two reason, in session_token is only savedd user side not on backend side. Second reason the session_token that is saved on client side, is a hashed token so we won't be able to have session.userId.
and also a user can have a session.userId, but we still need to verify what ever token is given. Please do not use this middleware as it doesn't work. Or modify it, in a way that does work. To figure what to see if it works or not, check other examples of how we logged user in, and verified their token.
There was a problem hiding this comment.
This is honestly no point of being here, as typeorm will naturally create your tables for you. And the migration-scripts for future reference are here not for migration but to allow for synchronizing testing across different development environments.
| @Field() | ||
| @Column() | ||
| text: string; | ||
|
|
There was a problem hiding this comment.
add this for proper type handling
@Field()
@Column()
dataType: "string" | "number"; // This allows us to make sure when we are registering, rendering on client or server side it is being handled properly
src/models/reviews/Review.ts
Outdated
|
|
||
| @ManyToOne("ReviewCampaign", (reviewCampaign: any) => reviewCampaign.reviews, { onDelete: "CASCADE" }) | ||
| @JoinColumn() | ||
| reviewCampaign: any; |
There was a problem hiding this comment.
This should not be type any, and don't put it in string. Instead have it be ReviewCampaign. This is a typescript backend, using type any ruins the whole point of choosing typescript for the backend
| @Field(() => DropDown, { nullable: true }) | ||
| @ManyToOne(() => DropDown, { nullable: true, onDelete: "SET NULL" }) | ||
| @JoinColumn() | ||
| dropDownAnswer: DropDown | null; |
There was a problem hiding this comment.
You have to provide a reference for dropDownAnswer to DropDown. This will return backend errors. And if the dropDown should delete then the Review Answer should be deleted as well
|
|
||
| // Review Mutations | ||
| @Mutation(() => Review) | ||
| async submitReview(@Arg("input") input: SubmitReviewInput) { |
There was a problem hiding this comment.
review needs to be associated to either people that bought ticket_id, or people registration list
| } | ||
|
|
||
| @Mutation(() => Review) | ||
| async updateReview(@Arg("input") input: UpdateReviewInput) { |
There was a problem hiding this comment.
review needs to be associated to either people that bought ticket_id, or people registration list
| } | ||
|
|
||
| // Review Queries | ||
| @Query(() => [Review]) |
There was a problem hiding this comment.
Before you can send review_campaign you need to verify user is logged in and authenticated. And your sending them the right review, and not sending them the wrong thing
| }); | ||
| } | ||
|
|
||
| @Query(() => Review, { nullable: true }) |
There was a problem hiding this comment.
Before you can send review_campaign you need to verify user is logged in and authenticated. And your sending them the right review, and not sending them the wrong thing
There was a problem hiding this comment.
delete this, or right better context
Implement createReviewCampaign mutation.