feat: implement pure CRUD operations for table entities#1831
Conversation
- Add PureCreateRowInTableUseCase for creating rows in tables. - Add PureDeleteRowFromTableUseCase for deleting rows from tables. - Add PureGetRowsFromTableUseCase for retrieving rows from tables. - Add PureReadRowFromTableUseCase for reading a single row by primary key. - Add PureUpdateRowInTableUseCase for updating rows in tables. - Define interfaces for CRUD use cases in table-pure-crud-use-cases.interface.ts. - Implement end-to-end tests for CRUD operations in non-saas-table-pure-crud-operations-e2e.test.ts.
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThis pull request introduces a Pure CRUD operations module enabling direct HTTP row-level create, read, update, delete, and list operations against database tables. The implementation includes DTOs, five use cases, a NestJS controller, module wiring, and comprehensive E2E tests covering all endpoints and error conditions. ChangesPure CRUD Operations Feature
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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.
Pull request overview
This PR introduces a new “pure” CRUD surface for table rows (create/read/update/delete + list) intended to return minimal payloads (only row or rows + pagination) and to be usable via API key access. It adds a dedicated Nest module/controller, corresponding use cases + data structures, and an end-to-end test suite for non‑SaaS flows.
Changes:
- Added
TablePureCrudOperationsModule+TablePureCrudOperationsControllerwith endpoints under/table/crud/*. - Implemented “pure” CRUD use cases and request/response data-structures for row operations.
- Added non‑SaaS AVA e2e coverage for create/read/update/delete + list rows (pagination/search/body filters).
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| backend/test/ava-tests/non-saas-tests/non-saas-table-pure-crud-operations-e2e.test.ts | New e2e tests validating pure CRUD endpoints return minimal payload shapes and expected behaviors. |
| backend/src/entities/table/table-pure-crud-operations/use-cases/table-pure-crud-use-cases.interface.ts | New interfaces defining the pure CRUD use case contracts. |
| backend/src/entities/table/table-pure-crud-operations/use-cases/pure-create-row-in-table.use.case.ts | Implements create-row use case returning only the created row. |
| backend/src/entities/table/table-pure-crud-operations/use-cases/pure-read-row-from-table.use.case.ts | Implements read-row-by-PK use case returning only the row. |
| backend/src/entities/table/table-pure-crud-operations/use-cases/pure-update-row-in-table.use.case.ts | Implements update-row-by-PK use case returning only the updated row. |
| backend/src/entities/table/table-pure-crud-operations/use-cases/pure-delete-row-from-table.use.case.ts | Implements delete-row-by-PK use case returning the deleted row. |
| backend/src/entities/table/table-pure-crud-operations/use-cases/pure-get-rows-from-table.use.case.ts | Implements rows listing with pagination/search/query/body-filters returning only rows + pagination. |
| backend/src/entities/table/table-pure-crud-operations/table-pure-crud-operations.module.ts | Wires up providers, controller, and middleware protection for the new routes. |
| backend/src/entities/table/table-pure-crud-operations/table-pure-crud-operations.controller.ts | Defines the new HTTP endpoints and request parsing (PK extraction, pagination parsing). |
| backend/src/entities/table/table-pure-crud-operations/application/data-structures/pure-create-row.ds.ts | New input DS for create row. |
| backend/src/entities/table/table-pure-crud-operations/application/data-structures/pure-read-row.ds.ts | New input DS for read row. |
| backend/src/entities/table/table-pure-crud-operations/application/data-structures/pure-update-row.ds.ts | New input DS for update row. |
| backend/src/entities/table/table-pure-crud-operations/application/data-structures/pure-delete-row.ds.ts | New input DS for delete row. |
| backend/src/entities/table/table-pure-crud-operations/application/data-structures/pure-get-rows.ds.ts | New input DS for list rows. |
| backend/src/entities/table/table-pure-crud-operations/application/data-structures/pure-crud-row-response.ds.ts | New minimal response DS for single-row responses. |
| backend/src/entities/table/table-pure-crud-operations/application/data-structures/pure-found-rows-response.ds.ts | New minimal response DS for list responses. |
| backend/src/common/data-injection.tokens.ts | Adds DI tokens for the new pure CRUD use cases. |
| backend/src/app.module.ts | Registers the new pure CRUD module in the main application module. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let parsedPage = 0; | ||
| let parsedPerPage = 0; | ||
| if (page && perPage) { | ||
| parsedPage = parseInt(page, 10); | ||
| parsedPerPage = parseInt(perPage, 10); | ||
| if ((parsedPage && parsedPage <= 0) || (parsedPerPage && parsedPerPage <= 0)) { | ||
| throw new HttpException({ message: Messages.PAGE_AND_PERPAGE_INVALID }, HttpStatus.BAD_REQUEST); | ||
| } | ||
| } |
| const primaryColumns = await dao.getTablePrimaryColumns(tableName, userEmail); | ||
| const primaryKey: Record<string, unknown> = {}; | ||
| for (const primaryColumn of primaryColumns) { | ||
| if (isObjectPropertyExists(primaryColumn, 'column_name')) { | ||
| primaryKey[primaryColumn.column_name] = query[primaryColumn.column_name]; | ||
| } | ||
| } | ||
| return primaryKey; |
| const addedRowPrimaryKey = (await dao.addRowInTable(tableName, row, userEmail)) as Record<string, unknown>; | ||
| if (!addedRowPrimaryKey || isObjectEmpty(addedRowPrimaryKey)) { | ||
| return { row }; | ||
| } |
Summary by CodeRabbit
Release Notes