Repository navigation
feat/issue 46 template details apis - #79
Basharkhan7776 merged 7 commits into
Conversation
ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
📜 Recent review details🧰 Additional context used🪛 Biome (2.5.1)apps/api/src/controllers/template.controller.ts[error] 156-156: expected (parse) [error] 156-156: expected (parse) [error] 156-156: expected (parse) [error] 474-474: expected (parse) [error] 476-476: expected (parse) [error] 477-477: Const declarations must have an initialized value. (parse) [error] 477-477: Expected a semicolon or an implicit semicolon after a statement, but found none (parse) [error] 477-478: Expected a statement but instead found ') (parse) 🪛 SQLFluff (4.2.2)packages/db/prisma/migrations/20260701000001_add_cloned_form_fk/migration.sql[error] 2-2: ADD CONSTRAINT ... FOREIGN KEY should use NOT VALID to avoid locking the table while validating existing rows. (PG01) 🛑 Comments failed to post (2)
🔇 Additional comments (2)
📝 WalkthroughWalkthroughAdds template detail, purchase, and review endpoints with new Prisma models, review validation, and controller logic for ownership checks, review aggregation, transactional cloning, and duplicate-prevention constraints. ChangesTemplate marketplace flow
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related issues
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 Biome (2.5.1)apps/api/src/controllers/template.controller.tsFile contains syntax errors that prevent linting: Line 156: expected 🔧 ESLint
ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/api/src/controllers/template.controller.ts`:
- Around line 139-141: The pagination logic in template.controller.ts currently
caps limit but leaves page unbounded, so reviewSkip can become an enormous
OFFSET. Update the page handling in the pagination block to validate page as a
safe positive integer and reject or cap overly large values before computing
reviewSkip, or change the endpoint to cursor-based pagination; keep the fix near
the existing req.query.page, req.query.limit, and reviewSkip calculations so
it’s easy to locate.
In `@packages/db/prisma/schema/templates.prisma`:
- Line 50: Add a database-level constraint for the template review rating field
because `TemplateReview.stars` is only documented as 1–5 in the Prisma schema.
Update the schema/migration around `template_reviews` so invalid values are
rejected at the DB layer, and ensure `avgStars` and related review stats can
only be computed from valid ratings.
- Around line 81-83: `clonedFormId` is currently only a nullable string in the
template schema, so Prisma does not enforce the intended link to `Form`; update
the `clonedFormId` field in the template model to use an optional `Form`
relation with `onDelete: SetNull`, and add the matching back-reference on `Form`
if the schema requires it so referential integrity and delete behavior are
enforced.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: caa2767b-ddf8-4797-85ee-7ae8393b9bf2
📒 Files selected for processing (5)
apps/api/src/controllers/template.controller.tsapps/api/src/lib/template-schemas.tsapps/api/src/routes/template/template.routes.tspackages/db/prisma/schema/templates.prismapackages/db/prisma/schema/user.prisma
📜 Review details
🔇 Additional comments (5)
packages/db/prisma/schema/templates.prisma (1)
32-42: LGTM!packages/db/prisma/schema/user.prisma (1)
30-35: LGTM!apps/api/src/lib/template-schemas.ts (1)
33-46: LGTM!apps/api/src/controllers/template.controller.ts (1)
145-224: LGTM!Also applies to: 234-331, 340-427
apps/api/src/routes/template/template.routes.ts (1)
4-28: LGTM!
- Cap pagination page to 1000 in template controller to prevent large offsets - Add database-level CHECK constraint for template_reviews stars (1-5) - Add proper foreign key relation for clonedFormId to Form model
|
@Basharkhan7776 |
Basharkhan7776
left a comment
There was a problem hiding this comment.
Good, resolve the issue will merge.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/api/src/controllers/template.controller.ts`:
- Around line 159-160: The public listing still accepts an unbounded page value,
so `skip` in `TemplateController` can become a huge OFFSET scan; clamp `page` to
the same safe-integer maximum used in `getTemplateById` before computing `skip`.
Update the `page` parsing logic in the listing handler so it uses the bounded
value, then derive `skip = (page - 1) * limit` from that capped page.
- Around line 150-151: The template lookup in the detail and purchase flows only
filters by id, which allows private templates to be fetched by anyone who knows
the ID. Update the query logic in template.controller.ts for the affected
detail/purchase handlers to also require the template to be public or owned by
the authenticated user, and return not found when a non-owner requests a private
template. Use the existing templateId lookup and request user context in those
controller methods to apply the access guard consistently in both places.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 7ca67f26-9763-4506-a86d-48acb561afde
📒 Files selected for processing (8)
apps/api/src/controllers/template.controller.tsapps/api/src/lib/template-schemas.tsapps/api/src/routes/template/template.routes.tspackages/db/prisma/migrations/20260701000000_add_stars_check/migration.sqlpackages/db/prisma/migrations/20260701000001_add_cloned_form_fk/migration.sqlpackages/db/prisma/schema/form.prismapackages/db/prisma/schema/templates.prismapackages/db/prisma/schema/user.prisma
📜 Review details
🧰 Additional context used
🪛 Biome (2.5.1)
apps/api/src/controllers/template.controller.ts
[error] 156-156: expected : but instead found const
(parse)
[error] 156-156: expected : but instead found getCommunityTemplates
(parse)
[error] 156-156: expected , but instead found :
(parse)
[error] 474-474: expected ) but instead found }
(parse)
[error] 476-476: expected , but instead found )
(parse)
[error] 477-477: Const declarations must have an initialized value.
(parse)
[error] 477-477: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 477-478: Expected a statement but instead found ')
])'.
(parse)
🪛 SQLFluff (4.2.2)
packages/db/prisma/migrations/20260701000001_add_cloned_form_fk/migration.sql
[error] 2-2: ADD CONSTRAINT ... FOREIGN KEY should use NOT VALID to avoid locking the table while validating existing rows.
(PG01)
🔇 Additional comments (2)
apps/api/src/controllers/template.controller.ts (1)
149-156: 🎯 Functional CorrectnessRestore the controller structure before merge.
packages/db/prisma/migrations/20260701000001_add_cloned_form_fk/migration.sql (1)
2-2: 🩺 Stability & AvailabilityConfirm the FK deployment path for existing rows. If
user_owned_templatesalready has data, add the constraint asNOT VALIDand validate it in a second step to avoid a longer lock during deploy.
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/api/src/controllers/template.controller.ts`:
- Around line 159-160: The public listing still accepts an unbounded page value,
so `skip` in `TemplateController` can become a huge OFFSET scan; clamp `page` to
the same safe-integer maximum used in `getTemplateById` before computing `skip`.
Update the `page` parsing logic in the listing handler so it uses the bounded
value, then derive `skip = (page - 1) * limit` from that capped page.
- Around line 150-151: The template lookup in the detail and purchase flows only
filters by id, which allows private templates to be fetched by anyone who knows
the ID. Update the query logic in template.controller.ts for the affected
detail/purchase handlers to also require the template to be public or owned by
the authenticated user, and return not found when a non-owner requests a private
template. Use the existing templateId lookup and request user context in those
controller methods to apply the access guard consistently in both places.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 7ca67f26-9763-4506-a86d-48acb561afde
📒 Files selected for processing (8)
apps/api/src/controllers/template.controller.tsapps/api/src/lib/template-schemas.tsapps/api/src/routes/template/template.routes.tspackages/db/prisma/migrations/20260701000000_add_stars_check/migration.sqlpackages/db/prisma/migrations/20260701000001_add_cloned_form_fk/migration.sqlpackages/db/prisma/schema/form.prismapackages/db/prisma/schema/templates.prismapackages/db/prisma/schema/user.prisma
📜 Review details
🔇 Additional comments (2)
apps/api/src/controllers/template.controller.ts (1)
149-156: 🎯 Functional CorrectnessRestore the controller structure before merge.
packages/db/prisma/migrations/20260701000001_add_cloned_form_fk/migration.sql (1)
2-2: 🩺 Stability & AvailabilityConfirm the FK deployment path for existing rows. If
user_owned_templatesalready has data, add the constraint asNOT VALIDand validate it in a second step to avoid a longer lock during deploy.
🛑 Comments failed to post (2)
apps/api/src/controllers/template.controller.ts (2)
150-151: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Guard private templates in the detail and purchase queries.
Both lookups only filter by
id. Any authenticated user who learns a private template ID can fetch its detail payload and clone it. Treat non-public templates as not found unless the requester is the owner.Also applies to: 286-287
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/api/src/controllers/template.controller.ts` around lines 150 - 151, The template lookup in the detail and purchase flows only filters by id, which allows private templates to be fetched by anyone who knows the ID. Update the query logic in template.controller.ts for the affected detail/purchase handlers to also require the template to be public or owned by the authenticated user, and return not found when a non-owner requests a private template. Use the existing templateId lookup and request user context in those controller methods to apply the access guard consistently in both places.
159-160: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win
Bound
pageon the public listing.
skip = (page - 1) * limitstill uses an unboundedpage, so/community?page=999999999can trigger very expensive OFFSET scans on an unauthenticated endpoint. Apply the same safe-integer cap used ingetTemplateByIdbefore computingskip.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/api/src/controllers/template.controller.ts` around lines 159 - 160, The public listing still accepts an unbounded page value, so `skip` in `TemplateController` can become a huge OFFSET scan; clamp `page` to the same safe-integer maximum used in `getTemplateById` before computing `skip`. Update the `page` parsing logic in the listing handler so it uses the bounded value, then derive `skip = (page - 1) * limit` from that capped page.
Give a summary atleast |
When a user purchases a template and wants to leave a review, should we make it compulsory to write a comment, or should we keep the comment optional and allow them to give only a star rating (1–5 stars) if they want? |
|
optional
|
Summary
Implements the [Block] Template/[id] APIs by introducing independent template cloning, paginated reviews, and strict purchase-based review eligibility.
Changes Made
UserOwnedTemplateandTemplateReviewmodels to the Prisma schema with explicit unique constraints and cascade deletes.POST /api/v1/templates/:id/purchaseto transactionally clone the template into an independent, unpublishedFormand link it viaclonedFormId.POST /api/v1/templates/:id/reviewswith strict validation to ensure only users with a valid purchase receipt (who are not the creator) can submit a review.GET /api/v1/templates/:idto fetch paginated reviews (?page=&limit=), star aggregations, and viewer context concurrently viaPromise.all.P2002errors to return409 Conflictfor duplicate purchases or reviews.CreateReviewSchema) with.trim()andmax(2000)for review text, and strict 1-5 integer bounds for star ratings.Testing
bun run buildpasses.npx prisma generatesucceeds without errors.Related Issues
Checklist
When a user purchases a template, it now creates a completely independent clone, ensuring that future changes by the template creator do not disrupt existing users.
Review eligibility is now strictly tied to purchasing, so only verified users can leave feedback on a template.
Template details now load much faster and support pagination, ensuring the page remains responsive even for templates with thousands of reviews.
Duplicate actions are safely blocked at the database level, preventing users from accidentally purchasing the same template twice or spamming reviews.
The review schema is designed to easily support future features like editing or deleting reviews without requiring major database migrations.