From 0a94567c8e8b6620f257859a36fe49e90742baae Mon Sep 17 00:00:00 2001 From: Mike <36415632+Mike-Heneghan@users.noreply.github.com> Date: Mon, 22 Jan 2024 13:45:45 +0000 Subject: [PATCH] feat: create feedback tables (#2679) * feat: add enum for feedback_type * feat: add table for feedback_status enum * feat: add table for storing user feedback * feat: add public insert permission to feedback table * chore: setup feedback_status_enum db tests * chore: setup feedback_type_enum db tests * chore: setup feedback db tests --- hasura.planx.uk/metadata/tables.yaml | 40 ++++++++ .../down.sql | 12 +++ .../up.sql | 12 +++ .../down.sql | 15 +++ .../up.sql | 17 ++++ .../down.sql | 5 + .../up.sql | 38 ++++++++ hasura.planx.uk/tests/feedback.test.js | 91 ++++++++++++++++++ hasura.planx.uk/tests/feedback_status.test.js | 92 +++++++++++++++++++ .../tests/feedback_type_enum.test.js | 92 +++++++++++++++++++ 10 files changed, 414 insertions(+) create mode 100644 hasura.planx.uk/migrations/1705407249614_squashed_add_feedback_type_enum/down.sql create mode 100644 hasura.planx.uk/migrations/1705407249614_squashed_add_feedback_type_enum/up.sql create mode 100644 hasura.planx.uk/migrations/1705408454440_squashed_add_feedback_status_enum/down.sql create mode 100644 hasura.planx.uk/migrations/1705408454440_squashed_add_feedback_status_enum/up.sql create mode 100644 hasura.planx.uk/migrations/1705424762267_squashed_create_table_public_feedback/down.sql create mode 100644 hasura.planx.uk/migrations/1705424762267_squashed_create_table_public_feedback/up.sql create mode 100644 hasura.planx.uk/tests/feedback.test.js create mode 100644 hasura.planx.uk/tests/feedback_status.test.js create mode 100644 hasura.planx.uk/tests/feedback_type_enum.test.js diff --git a/hasura.planx.uk/metadata/tables.yaml b/hasura.planx.uk/metadata/tables.yaml index d4880de914..82a3a1aca8 100644 --- a/hasura.planx.uk/metadata/tables.yaml +++ b/hasura.planx.uk/metadata/tables.yaml @@ -220,6 +220,46 @@ template_engine: Kriti url: '{{$base_url}}/webhooks/hasura/send-slack-notification' version: 2 +- table: + name: feedback + schema: public + object_relationships: + - name: flow + using: + foreign_key_constraint_on: flow_id + - name: team + using: + foreign_key_constraint_on: team_id + insert_permissions: + - role: public + permission: + check: {} + columns: + - address + - breadcrumbs + - component_metadata + - created_at + - device + - feedback_type + - flow_id + - help_text + - id + - node_id + - node_text + - project_type + - status + - team_id + - user_comment + - user_context + comment: Allow users who want to leave feedback on their experience to write to the table +- table: + name: feedback_status_enum + schema: public + is_enum: true +- table: + name: feedback_type_enum + schema: public + is_enum: true - table: name: flow_document_templates schema: public diff --git a/hasura.planx.uk/migrations/1705407249614_squashed_add_feedback_type_enum/down.sql b/hasura.planx.uk/migrations/1705407249614_squashed_add_feedback_type_enum/down.sql new file mode 100644 index 0000000000..571cd4b8d4 --- /dev/null +++ b/hasura.planx.uk/migrations/1705407249614_squashed_add_feedback_type_enum/down.sql @@ -0,0 +1,12 @@ + +DELETE FROM "public"."feedback_type_enum" WHERE "value" = 'helpful'; + +DELETE FROM "public"."feedback_type_enum" WHERE "value" = 'unhelpful'; + +DELETE FROM "public"."feedback_type_enum" WHERE "value" = 'comment'; + +DELETE FROM "public"."feedback_type_enum" WHERE "value" = 'idea'; + +DELETE FROM "public"."feedback_type_enum" WHERE "value" = 'issue'; + +DROP TABLE "public"."feedback_type_enum"; diff --git a/hasura.planx.uk/migrations/1705407249614_squashed_add_feedback_type_enum/up.sql b/hasura.planx.uk/migrations/1705407249614_squashed_add_feedback_type_enum/up.sql new file mode 100644 index 0000000000..d004f25cfe --- /dev/null +++ b/hasura.planx.uk/migrations/1705407249614_squashed_add_feedback_type_enum/up.sql @@ -0,0 +1,12 @@ + +CREATE TABLE "public"."feedback_type_enum" ("value" text NOT NULL, "comment" text NOT NULL, PRIMARY KEY ("value") );COMMENT ON TABLE "public"."feedback_type_enum" IS E'Store the different types of feedback we gather from user'; + +INSERT INTO "public"."feedback_type_enum"("value", "comment") VALUES (E'issue', E' A user reporting an issue with a service'); + +INSERT INTO "public"."feedback_type_enum"("value", "comment") VALUES (E'idea', E'A user has shared an idea'); + +INSERT INTO "public"."feedback_type_enum"("value", "comment") VALUES (E'comment', E'A user has shared a comment on a service'); + +INSERT INTO "public"."feedback_type_enum"("value", "comment") VALUES (E'unhelpful', E'A user has fed back that help text was unhelpful'); + +INSERT INTO "public"."feedback_type_enum"("value", "comment") VALUES (E'helpful', E'A user has fed back that help text was helpful'); diff --git a/hasura.planx.uk/migrations/1705408454440_squashed_add_feedback_status_enum/down.sql b/hasura.planx.uk/migrations/1705408454440_squashed_add_feedback_status_enum/down.sql new file mode 100644 index 0000000000..d5e3b42a7e --- /dev/null +++ b/hasura.planx.uk/migrations/1705408454440_squashed_add_feedback_status_enum/down.sql @@ -0,0 +1,15 @@ +DELETE FROM "public"."feedback_status" WHERE "value" = 'urgent'; + +DELETE FROM "public"."feedback_status" WHERE "value" = 'watch'; + +DELETE FROM "public"."feedback_status" WHERE "value" = 'maybe_in_future'; + +DELETE FROM "public"."feedback_status" WHERE "value" = 'no_action'; + +DELETE FROM "public"."feedback_status" WHERE "value" = 'doing'; + +DELETE FROM "public"."feedback_status" WHERE "value" = 'planned'; + +DELETE FROM "public"."feedback_status" WHERE "value" = 'done'; + +DROP TABLE "public"."feedback_status_enum"; diff --git a/hasura.planx.uk/migrations/1705408454440_squashed_add_feedback_status_enum/up.sql b/hasura.planx.uk/migrations/1705408454440_squashed_add_feedback_status_enum/up.sql new file mode 100644 index 0000000000..fba9306b10 --- /dev/null +++ b/hasura.planx.uk/migrations/1705408454440_squashed_add_feedback_status_enum/up.sql @@ -0,0 +1,17 @@ + +CREATE TABLE "public"."feedback_status_enum" ("value" text NOT NULL, "comment" text NOT NULL, PRIMARY KEY ("value") , UNIQUE ("value"));COMMENT ON TABLE "public"."feedback_status_enum" IS E'An enum for tracking the status of received feedback'; + +INSERT INTO "public"."feedback_status_enum"("value", "comment") VALUES (E'done', E'Any related actions have been completed'); + +INSERT INTO "public"."feedback_status_enum"("value", "comment") VALUES (E'planned', E'Related actions have been planned'); + +INSERT INTO "public"."feedback_status_enum"("value", "comment") VALUES (E'doing', E'Related actions are in progress'); + +INSERT INTO "public"."feedback_status_enum"("value", "comment") VALUES (E'no_action', E'It has been deemed there are no related actions'); + +INSERT INTO "public"."feedback_status_enum"("value", "comment") VALUES (E'maybe_in_future', E'Related actions might be considered in the future'); + +INSERT INTO "public"."feedback_status_enum"("value", "comment") VALUES (E'watch', E'Feedback of this time should be monitored'); + +INSERT INTO "public"."feedback_status_enum"("value", "comment") VALUES (E'urgent', E'This issue has been deemed urgent and related actions should be completed asap'); + diff --git a/hasura.planx.uk/migrations/1705424762267_squashed_create_table_public_feedback/down.sql b/hasura.planx.uk/migrations/1705424762267_squashed_create_table_public_feedback/down.sql new file mode 100644 index 0000000000..11d37f5954 --- /dev/null +++ b/hasura.planx.uk/migrations/1705424762267_squashed_create_table_public_feedback/down.sql @@ -0,0 +1,5 @@ +ALTER TABLE feedback DROP CONSTRAINT feedback_feedback_type_fkey; + +ALTER TABLE feedback DROP CONSTRAINT feedback_status_fkey; + +DROP TABLE public.feedback; \ No newline at end of file diff --git a/hasura.planx.uk/migrations/1705424762267_squashed_create_table_public_feedback/up.sql b/hasura.planx.uk/migrations/1705424762267_squashed_create_table_public_feedback/up.sql new file mode 100644 index 0000000000..086d0f978e --- /dev/null +++ b/hasura.planx.uk/migrations/1705424762267_squashed_create_table_public_feedback/up.sql @@ -0,0 +1,38 @@ +CREATE TABLE "public"."feedback" ( + "id" serial not null unique, + PRIMARY KEY ("id"), + "team_id" integer, + "flow_id" uuid, + "created_at" timestamptz NOT NULL DEFAULT now(), + "node_id" text, + "node_text" text, + "help_text" text, + "project_type" text, + "address" text, + "device" jsonb NOT NULL, + "breadcrumbs" jsonb NOT NULL, + "component_metadata" jsonb NOT NULL, + "user_context" text, + "user_comment" text NOT NULL, + "feedback_type" text NOT NULL, + "status" text, + FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON UPDATE restrict ON DELETE restrict, + FOREIGN KEY ("flow_id") REFERENCES "public"."flows"("id") ON UPDATE restrict ON DELETE restrict, + UNIQUE ("id") +); + +COMMENT ON TABLE "public"."feedback" IS E'A table for storing user feedback on services'; +COMMENT ON COLUMN "public"."feedback"."user_context" is E'User explanation of the context in which they\'re sharing comment'; +COMMENT ON COLUMN "public"."feedback"."user_comment" is E'The user\'s comment on the service'; +COMMENT ON COLUMN "public"."feedback"."status" is E'The status of our processing of the feedback'; + +ALTER TABLE + feedback +ADD + CONSTRAINT feedback_feedback_type_fkey FOREIGN KEY (feedback_type) REFERENCES feedback_type_enum; + +ALTER TABLE + feedback +ADD + CONSTRAINT feedback_status_fkey FOREIGN KEY (status) REFERENCES feedback_status_enum; + diff --git a/hasura.planx.uk/tests/feedback.test.js b/hasura.planx.uk/tests/feedback.test.js new file mode 100644 index 0000000000..e83df7537d --- /dev/null +++ b/hasura.planx.uk/tests/feedback.test.js @@ -0,0 +1,91 @@ +const { introspectAs } = require("./utils"); + +describe("feedback", () => { + describe("public", () => { + let i; + beforeAll(async () => { + i = await introspectAs("public"); + }); + + test("cannot query feedback", () => { + expect(i.queries).not.toContain("feedback"); + }); + + test("cannot update feedback", () => { + expect(i.mutations).not.toContain("update_feedback"); + expect(i.mutations).not.toContain("update_feedback_by_pk"); + }); + + test("cannot delete feedback", async () => { + expect(i.mutations).not.toContain("delete_feedback"); + }); + + test("can insert feedback", async () => { + expect(i.mutations).toContain("insert_feedback"); + }); + }); + + describe("admin", () => { + let i; + beforeAll(async () => { + i = await introspectAs("admin"); + }); + + test("has full access to query and mutate feedback", () => { + expect(i.mutations).toContain("insert_feedback"); + expect(i.mutations).toContain("insert_feedback_one"); + expect(i.mutations).toContain("update_feedback"); + expect(i.mutations).toContain("update_feedback_by_pk"); + expect(i.mutations).toContain("update_feedback_many"); + expect(i.mutations).toContain("delete_feedback"); + expect(i.mutations).toContain("delete_feedback_by_pk"); + }); + }); + + describe("platformAdmin", () => { + let i; + beforeAll(async () => { + i = await introspectAs("platformAdmin"); + }); + + test("cannot query feedback", () => { + expect(i.queries).not.toContain("feedback"); + + }); + + test("cannot mutate feedback", async () => { + expect(i).toHaveNoMutationsFor("feedback") + }); + }); + + describe("teamEditor", () => { + let i; + beforeAll(async () => { + i = await introspectAs("teamEditor"); + }); + + test("cannot query feedback", () => { + expect(i.queries).not.toContain("feedback"); + + }); + + test("cannot mutate feedback", async () => { + expect(i).toHaveNoMutationsFor("feedback") + }); + }); + + describe("api", () => { + let i; + beforeAll(async () => { + i = await introspectAs("api"); + }); + + test("cannot query feedback", () => { + expect(i.queries).not.toContain("feedback"); + }); + + test("cannot create, update, or delete teams", () => { + expect(i).toHaveNoMutationsFor("feedback"); + }); + }); +}); diff --git a/hasura.planx.uk/tests/feedback_status.test.js b/hasura.planx.uk/tests/feedback_status.test.js new file mode 100644 index 0000000000..d3483584d2 --- /dev/null +++ b/hasura.planx.uk/tests/feedback_status.test.js @@ -0,0 +1,92 @@ +const { introspectAs } = require("./utils"); + +describe("feedback_status_enum", () => { + describe("public", () => { + let i; + beforeAll(async () => { + i = await introspectAs("public"); + }); + + test("cannot INSERT records", () => { + expect(i.mutations).not.toContain("insert_feedback_status_enum"); + }); + + test("cannot QUERY records", () => { + expect(i.queries).not.toContain("feedback_status_enum"); + }); + + test("cannot DELETE records", () => { + expect(i.mutations).not.toContain("delete_feedback_status_enum"); + }); + + test("cannot UPDATE records", () => { + expect(i.mutations).not.toContain("update_feedback_status_enum"); + }); + }); + + describe("admin", () => { + let i; + beforeAll(async () => { + i = await introspectAs("admin"); + }); + + test("has full access to query and mutate feedback_status_enum", async () => { + expect(i.queries).toContain("feedback_status_enum"); + expect(i.mutations).toContain("insert_feedback_status_enum"); + expect(i.mutations).toContain("delete_feedback_status_enum"); + }); + }); + + describe("platformAdmin", () => { + let i; + beforeAll(async () => { + i = await introspectAs("platformAdmin"); + }); + + test("cannot query feedback_status_enum", () => { + expect(i.queries).not.toContain("feedback_status_enum"); + }); + + test("cannot create, update, or delete feedback_status_enum", () => { + expect(i).toHaveNoMutationsFor("feedback_status_enum"); + }); + }); + + describe("teamEditor", () => { + let i; + beforeAll(async () => { + i = await introspectAs("teamEditor"); + }); + + test("cannot query feedback_status_enum", () => { + expect(i.queries).not.toContain("feedback_status_enum"); + }); + + test("cannot create, update, or delete feedback_status_enum", () => { + expect(i).toHaveNoMutationsFor("feedback_status_enum"); + }); + }); + + describe("api", () => { + let i; + beforeAll(async () => { + i = await introspectAs("api"); + }); + + test("cannot INSERT records", () => { + expect(i.mutations).not.toContain("insert_feedback_status_enum"); + }); + + test("cannot QUERY records", () => { + expect(i.queries).not.toContain("feedback_status_enum"); + }); + + test("cannot DELETE records", () => { + expect(i.mutations).not.toContain("delete_feedback_status_enum"); + }); + + test("cannot UPDATE records", () => { + expect(i.mutations).not.toContain("update_feedback_status_enum"); + }); + }); + }); diff --git a/hasura.planx.uk/tests/feedback_type_enum.test.js b/hasura.planx.uk/tests/feedback_type_enum.test.js new file mode 100644 index 0000000000..b79d487bfe --- /dev/null +++ b/hasura.planx.uk/tests/feedback_type_enum.test.js @@ -0,0 +1,92 @@ +const { introspectAs } = require("./utils"); + +describe("feedback_type_enum", () => { + describe("public", () => { + let i; + beforeAll(async () => { + i = await introspectAs("public"); + }); + + test("cannot INSERT records", () => { + expect(i.mutations).not.toContain("insert_feedback_type_enum"); + }); + + test("cannot QUERY records", () => { + expect(i.queries).not.toContain("feedback_type_enum"); + }); + + test("cannot DELETE records", () => { + expect(i.mutations).not.toContain("delete_feedback_type_enum"); + }); + + test("cannot UPDATE records", () => { + expect(i.mutations).not.toContain("update_feedback_type_enum"); + }); + }); + + describe("admin", () => { + let i; + beforeAll(async () => { + i = await introspectAs("admin"); + }); + + test("has full access to query and mutate feedback_type_enum", async () => { + expect(i.queries).toContain("feedback_type_enum"); + expect(i.mutations).toContain("insert_feedback_type_enum"); + expect(i.mutations).toContain("delete_feedback_type_enum"); + }); + }); + + describe("platformAdmin", () => { + let i; + beforeAll(async () => { + i = await introspectAs("platformAdmin"); + }); + + test("cannot query feedback_type_enum", () => { + expect(i.queries).not.toContain("feedback_type_enum"); + }); + + test("cannot create, update, or delete feedback_type_enum", () => { + expect(i).toHaveNoMutationsFor("feedback_type_enum"); + }); + }); + + describe("teamEditor", () => { + let i; + beforeAll(async () => { + i = await introspectAs("teamEditor"); + }); + + test("cannot query feedback_type_enum", () => { + expect(i.queries).not.toContain("feedback_type_enum"); + }); + + test("cannot create, update, or delete feedback_type_enum", () => { + expect(i).toHaveNoMutationsFor("feedback_type_enum"); + }); + }); + + describe("api", () => { + let i; + beforeAll(async () => { + i = await introspectAs("api"); + }); + + test("cannot INSERT records", () => { + expect(i.mutations).not.toContain("insert_feedback_type_enum"); + }); + + test("cannot QUERY records", () => { + expect(i.queries).not.toContain("feedback_type_enum"); + }); + + test("cannot DELETE records", () => { + expect(i.mutations).not.toContain("delete_feedback_type_enum"); + }); + + test("cannot UPDATE records", () => { + expect(i.mutations).not.toContain("update_feedback_type_enum"); + }); + }); + });