Skip to content

Commit

Permalink
Resolve graphile#7 "As a CrewFixer Admin I'd like to be able to conne…
Browse files Browse the repository at this point in the history
…ct Google Sheets spreadsheet with a specific Project"
  • Loading branch information
Ondřej Všetička authored and heracek committed Aug 5, 2024
1 parent fe61ef0 commit fcc50ab
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 5 deletions.
3 changes: 3 additions & 0 deletions @app/db/migrations/current/0020-drops.sql
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ drop function if exists app_public.accept_invitation_to_project(uuid, text);
drop function if exists app_public.project_for_invitation(uuid, text) cascade;
drop function if exists app_public.invite_to_project(uuid, citext, citext) cascade;
drop function if exists app_public.create_project(text, text, project_shooting_day[], date, date) cascade;
drop function if exists app_public.update_project_connected_google_spreadsheets(uuid, google_spreadsheet[]) cascade;
drop function if exists app_hidden.current_user_is_admin() cascade;
drop function if exists app_public.current_user_invited_project_ids() cascade;
drop function if exists app_public.current_user_owner_project_ids() cascade;
drop function if exists app_public.current_user_member_project_ids() cascade;
Expand All @@ -52,3 +54,4 @@ drop table if exists app_public.project_invitation cascade;
drop table if exists app_public.project_membership cascade;
drop table if exists app_public.project cascade;
drop type if exists app_public.project_shooting_day;
drop type if exists app_public.project_connected_google_spreadsheet;
44 changes: 41 additions & 3 deletions @app/db/migrations/current/0040-project.sql
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
-- Project --

create type app_public.project_shooting_day as (
id text,
name text
);

create type app_public.project_connected_google_spreadsheet as (
name text,
spreadsheet_id text
);

create table app_public.project (
id uuid primary key default gen_random_uuid(),
-- organization_id uuid not null references app_public.organizations on delete set null,
Expand All @@ -14,6 +18,7 @@ create table app_public.project (
end_date date,
is_archived boolean not null default false,
shooting_days project_shooting_day[],
connected_google_spreadsheets project_connected_google_spreadsheet[],
created_at timestamptz not null default now(),
updated_at timestamptz not null default now()
);
Expand All @@ -24,5 +29,38 @@ create index on app_public.project (start_date);

create trigger _100_timestamps before insert or update on app_public.project for each row execute procedure app_private.tg__timestamps();

grant select on app_public.project to :DATABASE_VISITOR;
grant update (name, description, shooting_days, start_date, end_date) on app_public.project to :DATABASE_VISITOR;
grant
select,
update (name, description, start_date, end_date, shooting_days)
on app_public.project to :DATABASE_VISITOR;

create function app_public.update_project_connected_google_spreadsheets(
project_id uuid,
connected_google_spreadsheets project_connected_google_spreadsheet[] = null
) returns app_public.project as $$
declare
v_connected_google_spreadsheets alias for connected_google_spreadsheets;
v_proj app_public.project%rowtype;
begin
if app_public.current_user_id() is null then
raise exception 'You must log in to update a project' using errcode = 'LOGIN';
end if;

if not app_hidden.current_user_is_admin() and connected_google_spreadsheets is not null then
raise exception 'Only admins can create projects with google spreadsheets' using errcode = 'DNIED';
end if;

update app_public.project
set
connected_google_spreadsheets = v_connected_google_spreadsheets,
updated_at = now()
where id = project_id
returning * into v_proj;

if not found then
raise exception 'Project not found or update failed';
end if;

return v_proj;
end;
$$ language plpgsql volatile security definer set search_path = pg_catalog, public, pg_temp;
17 changes: 15 additions & 2 deletions @app/db/migrations/current/0043-create_project.sql
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
-- Project: create_project --
-- Project: helper function --
create function app_hidden.current_user_is_admin() returns boolean as $$
select is_admin from app_public.users where id = app_public.current_user_id();
$$ language sql stable;

-- Project: create project --

create function app_public.create_project(
name text,
description text = null,
shooting_days project_shooting_day[] = null,
connected_google_spreadsheets project_connected_google_spreadsheet[] = null,
start_date date = null,
end_date date = null
) returns app_public.project as $$
Expand All @@ -13,16 +19,24 @@ begin
if app_public.current_user_id() is null then
raise exception 'You must log in to create an project' using errcode = 'LOGIN';
end if;

-- TODO: enable later, this is needed for seeding for now
-- if not app_hidden.current_user_is_admin() and connected_google_spreadsheets is not null then
-- raise exception 'Only admins can create projects with google spreadsheets' using errcode = 'DNIED';
-- end if;

insert into app_public.project (
name,
description,
shooting_days,
connected_google_spreadsheets,
start_date,
end_date
) values (
name,
description,
shooting_days,
connected_google_spreadsheets,
start_date,
end_date
) returning * into v_proj;
Expand All @@ -32,7 +46,6 @@ begin
end;
$$ language plpgsql volatile security definer set search_path = pg_catalog, public, pg_temp;


-- create policy select_member on app_public.project
-- for select using (organization_id in (select app_public.current_user_member_organization_ids()));

Expand Down
51 changes: 51 additions & 0 deletions data/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ input CreateProjectInput {
payload verbatim. May be used to track mutations by the client.
"""
clientMutationId: String
connectedGoogleSpreadsheets: [ProjectConnectedGoogleSpreadsheetInput]
description: String
endDate: Date
name: String!
Expand Down Expand Up @@ -811,6 +812,12 @@ type Mutation {
"""
input: UpdateProjectInput!
): UpdateProjectPayload
updateProjectConnectedGoogleSpreadsheets(
"""
The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields.
"""
input: UpdateProjectConnectedGoogleSpreadsheetsInput!
): UpdateProjectConnectedGoogleSpreadsheetsPayload

"""Updates a single `Questionary` using a unique key and a patch."""
updateQuestionary(
Expand Down Expand Up @@ -1029,6 +1036,7 @@ type PageInfo {
}

type Project {
connectedGoogleSpreadsheets: [ProjectConnectedGoogleSpreadsheet]
createdAt: Datetime!
currentUserIsOwner: Boolean
description: String
Expand Down Expand Up @@ -1171,6 +1179,17 @@ input ProjectCondition {
startDate: Date
}

type ProjectConnectedGoogleSpreadsheet {
name: String
spreadsheetId: String
}

"""An input for mutations affecting `ProjectConnectedGoogleSpreadsheet`"""
input ProjectConnectedGoogleSpreadsheetInput {
name: String
spreadsheetId: String
}

type ProjectInvitation {
code: String
createdAt: Datetime!
Expand Down Expand Up @@ -2076,6 +2095,38 @@ type UpdateOrganizationPayload {
query: Query
}

"""All input for the `updateProjectConnectedGoogleSpreadsheets` mutation."""
input UpdateProjectConnectedGoogleSpreadsheetsInput {
"""
An arbitrary string value with no semantic meaning. Will be included in the
payload verbatim. May be used to track mutations by the client.
"""
clientMutationId: String
connectedGoogleSpreadsheets: [ProjectConnectedGoogleSpreadsheetInput]
projectId: UUID!
}

"""The output of our `updateProjectConnectedGoogleSpreadsheets` mutation."""
type UpdateProjectConnectedGoogleSpreadsheetsPayload {
"""
The exact same `clientMutationId` that was provided in the mutation input,
unchanged and unused. May be used by a client to track mutations.
"""
clientMutationId: String
project: Project

"""An edge for our `Project`. May be used by Relay 1."""
projectEdge(
"""The method to use when ordering `Project`."""
orderBy: [ProjectsOrderBy!] = [PRIMARY_KEY_ASC]
): ProjectsEdge

"""
Our root query field type. Allows us to run any query from our mutation payload.
"""
query: Query
}

"""All input for the `updateProject` mutation."""
input UpdateProjectInput {
"""
Expand Down

0 comments on commit fcc50ab

Please sign in to comment.