-
Notifications
You must be signed in to change notification settings - Fork 21
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
Feat: Add Edit/Delete dropdown #3592
Conversation
QA Summary
Test CoverageCoverage report for `packages/client`
Coverage report for `packages/server`
|
Terraform Summary
Hint: If "Terraform Format & Style" failed, run OutputValidation Output
Plan Summary
Pusher: @greg-adams, Action: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@greg-adams Everything looks good in testing! A couple server-side things to potentially address and/or get your take on.
const grantNote = knex | ||
.select('id') | ||
.from('grant_notes') | ||
.where({ grant_id: grantId, user_id: userId }); | ||
|
||
await knex('grant_notes_revisions') | ||
.whereIn('grant_note_id', grantNote) | ||
.del(); | ||
|
||
await grantNote.del(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be preferable to handle this on the Postgres side using ON DELETE CASCADE
. Unfortunately, that doesn't currently seem to be implemented on the FK constraint, so it's probably best that we do that now since there's no data in Production just yet.
A few details that feel worth mentioning:
- Postgres doesn't support this kind of alteration on foreign keys, so the migration will need to drop the existing FK constraint and then re-add it with the
ON DELETE CASCADE
specification. - Knex seems to have its own naming convention for foreign key constraints (it doesn't follow the Postgres standard convention of
{tablename}_{columnname(s)}_{suffix}
) so rather than usingknex.raw()
, it might be best to use the Knex schema builder functions (seetable.dropForeign()
andtable.foreign()
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes certainly makes sense here - updated!
packages/server/src/routes/grants.js
Outdated
// sending the notes as JSON response | ||
res.json(notes); | ||
} catch (error) { | ||
res.status(500).json({ error: 'Failed to retrieve notes' }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to re-throw error
on the next line so that we can preserve the error/trace details, or will that mess with the ability to provide the Failed to retrieve notes
message in the response?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, I removed the try..catch here as we aren't using this message on the FE and will still result in a 500
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@greg-adams A few quick suggestions for the new Postgres function, but I think this is otherwise ready.
const ON_UPDATE_TIMESTAMP_FUNCTION = ` | ||
CREATE OR REPLACE FUNCTION on_update_timestamp() | ||
RETURNS trigger AS $$ | ||
BEGIN | ||
NEW.updated_at = now(); | ||
RETURN NEW; | ||
END; | ||
$$ language 'plpgsql'; | ||
`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW when you asked me about this is Slack I thought you confirming that updated_at
columns should have a DEFAULT now()
specification rather than ensuring that these column updates should happen automatically 😄
That said, this seems like a nice behavior to have on-hand, and is more comprehensive than a simple default. 👍 !
BEGIN | ||
NEW.updated_at = now(); | ||
RETURN NEW; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Slight tweak that avoids setting updated_at
if the update operation isn't actually changing the row (e.g. UPDATE my_table SET my_col = 123
when my_col
is already 123
):
BEGIN | |
NEW.updated_at = now(); | |
RETURN NEW; | |
BEGIN | |
IF NEW IS DISTINCT FROM OLD THEN | |
NEW.updated_at = now(); | |
END IF; | |
RETURN NEW; | |
END; |
*/ | ||
exports.up = async function (knex) { | ||
const ON_UPDATE_TIMESTAMP_FUNCTION = ` | ||
CREATE OR REPLACE FUNCTION on_update_timestamp() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just making it a bit easier to locate quickly during a psql
session :)
CREATE OR REPLACE FUNCTION on_update_timestamp() | |
CREATE OR REPLACE FUNCTION before_update_set_updated_at() |
packages/server/knexfile.js
Outdated
// Set trigger for any updated timestamps | ||
onUpdateTrigger: (table) => ` | ||
CREATE TRIGGER ${table}_updated_at BEFORE UPDATE ON ${table} | ||
FOR EACH ROW EXECUTE PROCEDURE on_update_timestamp(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per my previous comment
FOR EACH ROW EXECUTE PROCEDURE on_update_timestamp(); | |
FOR EACH ROW EXECUTE PROCEDURE before_update_set_updated_at(); |
@TylerHendrickson thanks! I incorporated your changes and some small changes to another migration |
e287c45
to
56ddc97
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@greg-adams Looks good to me!
@@ -17,7 +17,8 @@ exports.up = function (knex) { | |||
* @param { import("knex").Knex } knex | |||
* @returns { Promise<void> } | |||
*/ | |||
exports.down = function (knex) { | |||
exports.down = async function (knex) { | |||
await knex('email_subscriptions').where({ notification_type: 'GRANT_ACTIVITY' }).del(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch 👍
Ticket #3591
Description
grant_notes
table to support soft-delete of notes:is_published
andupdated_at
Screenshots / Demo Video
Testing
Automated and Unit Tests
Manual tests for Reviewer
Checklist