Skip to content

Added mutations for action Item Category #3432

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

Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
996dc79
Added mutations for action Item Category
NishantSinghhhhh Apr 6, 2025
5c86d3b
Merge branch 'develop-postgres' into ActionItemCategory
NishantSinghhhhh Apr 7, 2025
75d910e
Added tests
NishantSinghhhhh Apr 7, 2025
04eba4f
Added test for createAction Item Category
NishantSinghhhhh Apr 9, 2025
0bb9e11
rabbits changes
NishantSinghhhhh Apr 9, 2025
c123acb
rabbits changes
NishantSinghhhhh Apr 9, 2025
0a07f4f
rabbits changes
NishantSinghhhhh Apr 9, 2025
5858194
rabbits changes
NishantSinghhhhh Apr 9, 2025
3645672
Merge branch 'develop-postgres' into ActionItemCategory
NishantSinghhhhh Apr 10, 2025
3372bd2
Created an input type for createActionItem
NishantSinghhhhh Apr 10, 2025
f689e29
Created an input type for createActionItem
NishantSinghhhhh Apr 10, 2025
cc2e986
Created an input type for createActionItem
NishantSinghhhhh Apr 10, 2025
9e3bb02
Created an input type for createActionItem
NishantSinghhhhh Apr 10, 2025
b03f5c2
Added types for 2 mutations and edited 1 mutation named createActionI…
NishantSinghhhhh Apr 10, 2025
040fef1
Merge branch 'develop-postgres' into ActionItemCategory
NishantSinghhhhh Apr 12, 2025
0143f00
changed files
NishantSinghhhhh Apr 14, 2025
ce056bc
Addedd changes
NishantSinghhhhh Apr 16, 2025
4889eeb
Merge branch 'ActionItemCategory' of https://github.com/NishantSinghh…
NishantSinghhhhh Apr 16, 2025
255c319
Added changes
NishantSinghhhhh Apr 18, 2025
6e3ce55
Added changes
NishantSinghhhhh Apr 18, 2025
8ffa4f0
Added changes
NishantSinghhhhh Apr 18, 2025
5ce99b4
Added changes
NishantSinghhhhh Apr 18, 2025
0ac4781
Added changes
NishantSinghhhhh Apr 18, 2025
4efeea4
Added changes
NishantSinghhhhh Apr 18, 2025
66de1bd
Added changes
NishantSinghhhhh Apr 18, 2025
e736e0a
Added changes
NishantSinghhhhh Apr 18, 2025
a2d07f1
Added changes
NishantSinghhhhh Apr 18, 2025
eaa3b9f
Added tests
NishantSinghhhhh Apr 18, 2025
56b290c
Added tests
NishantSinghhhhh Apr 18, 2025
00646cd
Added tests
NishantSinghhhhh Apr 18, 2025
b6d8ade
Added tests
NishantSinghhhhh Apr 18, 2025
335a92d
Added tests
NishantSinghhhhh Apr 18, 2025
1f96ef2
Added tests
NishantSinghhhhh Apr 18, 2025
95fdf64
Merge branch 'develop-postgres' into ActionItemCategory
NishantSinghhhhh Apr 18, 2025
267bb0c
Added tests
NishantSinghhhhh Apr 18, 2025
86c83e4
Added tests
NishantSinghhhhh Apr 18, 2025
6127a9a
Added tests
NishantSinghhhhh Apr 18, 2025
31b85f0
Added tests
NishantSinghhhhh Apr 18, 2025
8d5649d
Added tests
NishantSinghhhhh Apr 18, 2025
43ce3ff
Added tests
NishantSinghhhhh Apr 18, 2025
0b7b030
Added tests
NishantSinghhhhh Apr 18, 2025
a473043
Added alloted hours
NishantSinghhhhh Apr 21, 2025
b918f6d
Added changes
NishantSinghhhhh Apr 21, 2025
42610e6
Merge branch 'develop-postgres' into ActionItemCategory
NishantSinghhhhh Apr 21, 2025
9f8d528
Added changes
NishantSinghhhhh Apr 22, 2025
8fb5aa8
'Merge branch 'ActionItemCategory' of https://github.com/NishantSingh…
NishantSinghhhhh Apr 22, 2025
f1b412c
removed type errors
NishantSinghhhhh Apr 22, 2025
0eb60de
removed type errors
NishantSinghhhhh Apr 22, 2025
d8a85ca
removed type errors
NishantSinghhhhh Apr 22, 2025
fa3373a
changed names of tables
NishantSinghhhhh Apr 22, 2025
24804c3
Added alloted hours data in sample data for actionItems
NishantSinghhhhh Apr 22, 2025
c5a75eb
Added alloted hours data in sample data for actionItems
NishantSinghhhhh Apr 22, 2025
280ed54
Added alloted hours data in sample data for actionItems
NishantSinghhhhh Apr 22, 2025
a0ea106
Added changes in table
NishantSinghhhhh Apr 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,12 @@ type Community {
youtubeURL: String
}

input CreateActionItemCategoryInput {
isDisabled: Boolean
name: String!
organizationId: ID!
}

input CreateActionItemInput {
assignedAt: String
assigneeId: ID!
Expand Down Expand Up @@ -773,6 +779,11 @@ type GetUrlResponse {
presignedUrl: String
}

type HasUserVoted {
"""Type of the post vote"""
type: PostVoteType!
}

"""
Possible variants of the two-letter language code defined in ISO 639-1, part of the ISO 639 standard published by the International Organization for Standardization (ISO), to represent natural languages.
"""
Expand Down Expand Up @@ -1472,6 +1483,9 @@ type Mutation {
"""Mutation field to create an action item."""
createActionItem(input: CreateActionItemInput!): ActionItem

"""Mutation field to create a new Action Item Category."""
createActionItemCategory(input: CreateActionItemCategoryInput!): ActionItemCategory

"""Mutation field to create an advertisement."""
createAdvertisement(input: MutationCreateAdvertisementInput!): Advertisement

Expand Down Expand Up @@ -1646,6 +1660,9 @@ type Mutation {
input: MutationUpdateActionItemInput!
): ActionItem

"""Mutation field to update an existing Action Item Category."""
updateActionItemCategory(input: UpdateActionItemCategoryInput!): ActionItemCategory

"""Mutation field to update an advertisement."""
updateAdvertisement(input: MutationUpdateAdvertisementInput!): Advertisement

Expand Down Expand Up @@ -3360,7 +3377,7 @@ type Query {
fundCampaignPledge(input: QueryFundCampaignPledgeInput!): FundCampaignPledge

"""Query field to read a post vote."""
hasUserVoted(input: QueryHasUserVotedInput!): hasUserVoted
hasUserVoted(input: QueryHasUserVotedInput!): HasUserVoted

"""Query field to read an organization."""
organization(input: QueryOrganizationInput!): Organization
Expand Down Expand Up @@ -3666,6 +3683,12 @@ type TagFolderTagsConnectionEdge {
node: Tag
}

input UpdateActionItemCategoryInput {
categoryId: ID!
isDisabled: Boolean
name: String
}

"""The `Upload` scalar type represents a file upload."""
scalar Upload

Expand Down Expand Up @@ -3894,9 +3917,4 @@ type VenueEventsConnection {
type VenueEventsConnectionEdge {
cursor: String!
node: Event
}

type hasUserVoted {
"""Type of the post vote"""
type: PostVoteType!
}
5 changes: 0 additions & 5 deletions src/createServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,6 @@ export const createServer = async (options?: {
closeClient: true,
});

// fastify.register(fastifyRedis, {
// url: fastify.envConfig.API_REDIS_URI,
// closeClient: true,
// });

// More information at this link: https://github.com/fastify/fastify-jwt
fastify.register(fastifyJwt, {
secret: fastify.envConfig.API_JWT_SECRET,
Expand Down
4 changes: 0 additions & 4 deletions src/envConfigSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,10 +240,6 @@ export const envConfigSchema = Type.Object({
maximum: 65535,
minimum: 0,
}),
// API_REDIS_URI: Type.String({
// format: "uri",
// pattern: "^redis://.*",
// }),

API_GRAPHQL_SCALAR_FIELD_COST: Type.Number({
minimum: 0,
Expand Down
124 changes: 124 additions & 0 deletions src/graphql/types/Mutation/createActionItemCategory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { sql } from "drizzle-orm";
import { uuidv7 } from "uuidv7";
import { z } from "zod";
import { actionCategoriesTable } from "~/src/drizzle/tables/actionCategories";
import { builder } from "~/src/graphql/builder";
import { TalawaGraphQLError } from "~/src/utilities/TalawaGraphQLError";

// 1. Define your ActionItemCategory GraphQL output type (example)
import { ActionItemCategory } from "../ActionItemCategory/ActionItemCategory";

// 2. Create Zod schema for input validation
const mutationCreateActionItemCategoryArgumentsSchema = z.object({
input: z.object({
name: z.string().min(1, "Category name cannot be empty"),
organizationId: z.string().uuid(),
// Optional fields like isDisabled, if you allow it to be set:
isDisabled: z.boolean().optional(),
}),
});

builder.mutationField("createActionItemCategory", (t) =>
t.field({
type: ActionItemCategory, // The return type
args: {
input: t.arg({
required: true,
type: builder.inputType("CreateActionItemCategoryInput", {
fields: (t) => ({
name: t.field({ type: "String", required: true }),
organizationId: t.field({ type: "ID", required: true }),
isDisabled: t.field({ type: "Boolean" }), // Allow setting isDisabled from input
}),
}),
}),
},
description: "Mutation field to create a new Action Item Category.",
resolve: async (_parent, args, ctx) => {
// 4. Check authentication
if (!ctx.currentClient.isAuthenticated) {
throw new TalawaGraphQLError({
extensions: { code: "unauthenticated" },
});
}

Check warning on line 43 in src/graphql/types/Mutation/createActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/createActionItemCategory.ts#L39-L43

Added lines #L39 - L43 were not covered by tests

// 5. Validate input with Zod
const parsedArgs =
mutationCreateActionItemCategoryArgumentsSchema.parse(args);
const currentUserId = ctx.currentClient.user.id;

Check warning on line 48 in src/graphql/types/Mutation/createActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/createActionItemCategory.ts#L46-L48

Added lines #L46 - L48 were not covered by tests

// 6. Check if the organization exists
const existingOrganization =
await ctx.drizzleClient.query.organizationsTable.findFirst({
columns: { id: true },
where: (fields, operators) =>
operators.eq(fields.id, parsedArgs.input.organizationId),
});

Check warning on line 56 in src/graphql/types/Mutation/createActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/createActionItemCategory.ts#L51-L56

Added lines #L51 - L56 were not covered by tests

if (!existingOrganization) {
throw new TalawaGraphQLError({
extensions: {
code: "arguments_associated_resources_not_found",
issues: [{ argumentPath: ["input", "organizationId"] }],
},
});
}

Check warning on line 65 in src/graphql/types/Mutation/createActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/createActionItemCategory.ts#L58-L65

Added lines #L58 - L65 were not covered by tests

// 7. Check if the user is part of the organization
const userMembership =
await ctx.drizzleClient.query.organizationMembershipsTable.findFirst({
columns: { role: true },
where: (fields, operators) =>
sql`${operators.eq(fields.memberId, currentUserId)}
AND ${operators.eq(fields.organizationId, parsedArgs.input.organizationId)}`,
});

Check warning on line 74 in src/graphql/types/Mutation/createActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/createActionItemCategory.ts#L68-L74

Added lines #L68 - L74 were not covered by tests

if (!userMembership) {
throw new TalawaGraphQLError({
extensions: {
code: "unauthorized_action_on_arguments_associated_resources",
issues: [{ argumentPath: ["input", "organizationId"] }],
},
});
}

Check warning on line 83 in src/graphql/types/Mutation/createActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/createActionItemCategory.ts#L76-L83

Added lines #L76 - L83 were not covered by tests

// 8. Check if the user is an admin (similar logic as action item creation)
if (userMembership.role !== "administrator") {
throw new TalawaGraphQLError({
extensions: {
code: "forbidden_action_on_arguments_associated_resources",
issues: [
{
argumentPath: ["input", "organizationId"],
message:
"Only administrators can create categories for this organization.",
},
],
},
});
}

Check warning on line 99 in src/graphql/types/Mutation/createActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/createActionItemCategory.ts#L86-L99

Added lines #L86 - L99 were not covered by tests

const [createdCategory] = await ctx.drizzleClient
.insert(actionCategoriesTable)
.values({
id: uuidv7(),
name: parsedArgs.input.name,
organizationId: parsedArgs.input.organizationId,
creatorId: currentUserId,
isDisabled: parsedArgs.input.isDisabled ?? false,
createdAt: new Date(),
updatedAt: new Date(),
})
.returning();

Check warning on line 112 in src/graphql/types/Mutation/createActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/createActionItemCategory.ts#L101-L112

Added lines #L101 - L112 were not covered by tests

if (!createdCategory) {
ctx.log.error(
"Postgres insert operation unexpectedly returned an empty array.",
);
throw new TalawaGraphQLError({ extensions: { code: "unexpected" } });
}

Check warning on line 119 in src/graphql/types/Mutation/createActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/createActionItemCategory.ts#L114-L119

Added lines #L114 - L119 were not covered by tests

return createdCategory;
},

Check warning on line 122 in src/graphql/types/Mutation/createActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/createActionItemCategory.ts#L121-L122

Added lines #L121 - L122 were not covered by tests
}),
);
2 changes: 2 additions & 0 deletions src/graphql/types/Mutation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,5 @@ import "./createPresignedUrl";
import "./deleteActionItem";
import "./updateActionItem";
import "./createActionItem";
import "./createActionItemCategory";
import "./updateActionItemCategory";
116 changes: 116 additions & 0 deletions src/graphql/types/Mutation/updateActionItemCategory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { eq, sql } from "drizzle-orm";
import { z } from "zod";
import { actionCategoriesTable } from "~/src/drizzle/tables/actionCategories";
import { builder } from "~/src/graphql/builder";
import { TalawaGraphQLError } from "~/src/utilities/TalawaGraphQLError";
import { ActionItemCategory } from "../ActionItemCategory/ActionItemCategory";

const mutationUpdateActionItemCategoryArgumentsSchema = z.object({
input: z.object({
categoryId: z.string().uuid(), // The ID of the category to update
name: z.string().optional(), // New name
isDisabled: z.boolean().optional(), // Enable/disable
}),
});

builder.mutationField("updateActionItemCategory", (t) =>
t.field({
type: ActionItemCategory,
args: {
input: t.arg({
required: true,
type: builder.inputType("UpdateActionItemCategoryInput", {
fields: (t) => ({
categoryId: t.field({ type: "ID", required: true }),
name: t.field({ type: "String" }),
isDisabled: t.field({ type: "Boolean" }),
}),
}),
}),
},
description: "Mutation field to update an existing Action Item Category.",
resolve: async (_parent, args, ctx) => {
// 1. Check user authentication
if (!ctx.currentClient.isAuthenticated) {
throw new TalawaGraphQLError({
extensions: { code: "unauthenticated" },
});
}

Check warning on line 38 in src/graphql/types/Mutation/updateActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/updateActionItemCategory.ts#L34-L38

Added lines #L34 - L38 were not covered by tests

// 2. Validate input
const parsedArgs =
mutationUpdateActionItemCategoryArgumentsSchema.parse(args);
const { categoryId, name, isDisabled } = parsedArgs.input;
const currentUserId = ctx.currentClient.user.id;

Check warning on line 44 in src/graphql/types/Mutation/updateActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/updateActionItemCategory.ts#L41-L44

Added lines #L41 - L44 were not covered by tests

// 3. Find the existing category
const existingCategory =
await ctx.drizzleClient.query.actionCategoriesTable.findFirst({
columns: {
id: true,
organizationId: true,
},
where: (fields, operators) => operators.eq(fields.id, categoryId),
});

Check warning on line 54 in src/graphql/types/Mutation/updateActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/updateActionItemCategory.ts#L47-L54

Added lines #L47 - L54 were not covered by tests

if (!existingCategory) {
throw new TalawaGraphQLError({
extensions: {
code: "arguments_associated_resources_not_found",
issues: [{ argumentPath: ["input", "categoryId"] }],
},
});
}

Check warning on line 63 in src/graphql/types/Mutation/updateActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/updateActionItemCategory.ts#L56-L63

Added lines #L56 - L63 were not covered by tests

// 4. Check if the user is an admin in that category's organization
const userMembership =
await ctx.drizzleClient.query.organizationMembershipsTable.findFirst({
columns: { role: true },
where: (fields, operators) =>
sql`${operators.eq(fields.memberId, currentUserId)}
AND ${operators.eq(fields.organizationId, existingCategory.organizationId)}`,
});

Check warning on line 72 in src/graphql/types/Mutation/updateActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/updateActionItemCategory.ts#L66-L72

Added lines #L66 - L72 were not covered by tests

if (!userMembership || userMembership.role !== "administrator") {
throw new TalawaGraphQLError({
extensions: {
code: "forbidden_action_on_arguments_associated_resources",
issues: [
{
argumentPath: ["input", "categoryId"],
message: "Only administrators can update this category.",
},
],
},
});
}

Check warning on line 86 in src/graphql/types/Mutation/updateActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/updateActionItemCategory.ts#L74-L86

Added lines #L74 - L86 were not covered by tests

// 5. Update the category
// Build a "set" object only with provided fields
const updates: Record<string, unknown> = { updatedAt: new Date() };
if (typeof name === "string") {
updates.name = name;
}
if (typeof isDisabled === "boolean") {
updates.isDisabled = isDisabled;
}

Check warning on line 96 in src/graphql/types/Mutation/updateActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/updateActionItemCategory.ts#L90-L96

Added lines #L90 - L96 were not covered by tests

// ...

const [updatedCategory] = await ctx.drizzleClient
.update(actionCategoriesTable)
.set(updates)
.where(eq(actionCategoriesTable.id, categoryId))
.returning();

Check warning on line 104 in src/graphql/types/Mutation/updateActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/updateActionItemCategory.ts#L100-L104

Added lines #L100 - L104 were not covered by tests

if (!updatedCategory) {
ctx.log.error(
"Postgres update operation unexpectedly returned an empty array.",
);
throw new TalawaGraphQLError({ extensions: { code: "unexpected" } });
}

Check warning on line 111 in src/graphql/types/Mutation/updateActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/updateActionItemCategory.ts#L106-L111

Added lines #L106 - L111 were not covered by tests

return updatedCategory;
},

Check warning on line 114 in src/graphql/types/Mutation/updateActionItemCategory.ts

View check run for this annotation

Codecov / codecov/patch

src/graphql/types/Mutation/updateActionItemCategory.ts#L113-L114

Added lines #L113 - L114 were not covered by tests
}),
);
Empty file.
8 changes: 5 additions & 3 deletions test/graphql/types/gql.tada.d.ts

Large diffs are not rendered by default.

Loading