Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 10 additions & 0 deletions packages/api/src/lib/webhook-events.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,11 @@ describe("Webhook Events", () => {
parentId: region.id,
isActive: true,
email: null,
description: null,
website: null,
twitter: null,
facebook: null,
instagram: null,
});

if (result.org) {
Expand Down Expand Up @@ -516,6 +521,11 @@ describe("Webhook Events", () => {
parentId: region.id,
isActive: true,
email: null,
description: null,
website: null,
twitter: null,
facebook: null,
instagram: null,
});

// Verify notifyWebhooks was called with correct payload
Expand Down
20 changes: 20 additions & 0 deletions packages/api/src/router/org.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,11 @@ describe("Org Router", () => {
parentId: f3Nation.id,
isActive: true,
email: "test@example.com",
description: null,
website: null,
twitter: null,
facebook: null,
instagram: null,
});

expect(result).toHaveProperty("org");
Expand All @@ -233,6 +238,11 @@ describe("Org Router", () => {
orgType: "region",
isActive: true,
email: "test@example.com",
description: null,
website: null,
twitter: null,
facebook: null,
instagram: null,
}),
).rejects.toThrow("Parent ID or ID is required");
});
Expand Down Expand Up @@ -269,6 +279,11 @@ describe("Org Router", () => {
parentId: f3Nation.id,
isActive: true,
email: "test@example.com",
description: null,
website: null,
twitter: null,
facebook: null,
instagram: null,
});

expect(result.org?.id).toBe(testOrg.id);
Expand All @@ -294,6 +309,11 @@ describe("Org Router", () => {
parentId: f3Nation.id,
isActive: true,
email: "test@example.com",
description: null,
website: null,
twitter: null,
facebook: null,
instagram: null,
}),
).rejects.toThrow();
});
Expand Down
98 changes: 91 additions & 7 deletions packages/validators/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import { z } from "zod";

import {
events,
eventTags,
eventTypes,
locations,
orgs,
slackSpaces,
slackUsers,
updateRequests,
users,
} from "@acme/db/schema/schema";
Expand Down Expand Up @@ -52,6 +55,10 @@ export const EventTypeInsertSchema = createInsertSchema(eventTypes, {
});
export const EventTypeSelectSchema = createSelectSchema(eventTypes);

// EVENT TAG SCHEMA
export const EventTagInsertSchema = createInsertSchema(eventTags);
export const EventTagSelectSchema = createSelectSchema(eventTags);

// EVENT SCHEMA
export const EventInsertSchema = createInsertSchema(events, {
name: (s: z.ZodString) => s.min(1, { message: "Name is required" }),
Expand All @@ -77,6 +84,7 @@ export const EventInsertSchema = createInsertSchema(events, {
.number()
.array()
.min(1, { message: "Event type is required" }),
eventTagIds: z.number().array().optional(),
})
.omit({
orgId: true,
Expand All @@ -94,7 +102,12 @@ export type EventInsertType = z.infer<typeof CreateEventSchema>;
export const NationInsertSchema = createInsertSchema(orgs, {
name: (s: z.ZodString) => s.min(1, { message: "Name is required" }),
email: (s: z.ZodString) =>
s.email({ message: "Invalid email format" }).or(z.literal("")),
s.email({ message: "Invalid email format" }).or(z.literal("")).nullable(),
description: (s: z.ZodString) => s.nullable(),
website: (s: z.ZodString) => s.nullable(),
twitter: (s: z.ZodString) => s.nullable(),
facebook: (s: z.ZodString) => s.nullable(),
instagram: (s: z.ZodString) => s.nullable(),
parentId: z.null({ message: "Must not have a parent" }).optional(),
}).omit({ orgType: true });
export const NationSelectSchema = createSelectSchema(orgs);
Expand All @@ -106,7 +119,12 @@ export const SectorInsertSchema = createInsertSchema(orgs, {
.number({ message: "Must have a parent" })
.nonnegative({ message: "Invalid selection" }),
email: (s: z.ZodString) =>
s.email({ message: "Invalid email format" }).or(z.literal("")),
s.email({ message: "Invalid email format" }).or(z.literal("")).nullable(),
description: (s: z.ZodString) => s.nullable(),
website: (s: z.ZodString) => s.nullable(),
twitter: (s: z.ZodString) => s.nullable(),
facebook: (s: z.ZodString) => s.nullable(),
instagram: (s: z.ZodString) => s.nullable(),
}).omit({ orgType: true });
export const SectorSelectSchema = createSelectSchema(orgs);

Expand All @@ -117,7 +135,12 @@ export const AreaInsertSchema = createInsertSchema(orgs, {
.number({ message: "Must have a parent" })
.nonnegative({ message: "Invalid selection" }),
email: (s: z.ZodString) =>
s.email({ message: "Invalid email format" }).or(z.literal("")),
s.email({ message: "Invalid email format" }).or(z.literal("")).nullable(),
description: (s: z.ZodString) => s.nullable(),
website: (s: z.ZodString) => s.nullable(),
twitter: (s: z.ZodString) => s.nullable(),
facebook: (s: z.ZodString) => s.nullable(),
instagram: (s: z.ZodString) => s.nullable(),
}).omit({ orgType: true });
export const AreaSelectSchema = createSelectSchema(orgs);

Expand All @@ -128,7 +151,12 @@ export const RegionInsertSchema = createInsertSchema(orgs, {
.number({ message: "Must have a parent" })
.nonnegative({ message: "Invalid selection" }),
email: (s: z.ZodString) =>
s.email({ message: "Invalid email format" }).or(z.literal("")),
s.email({ message: "Invalid email format" }).or(z.literal("")).nullable(),
description: (s: z.ZodString) => s.nullable(),
website: (s: z.ZodString) => s.nullable(),
twitter: (s: z.ZodString) => s.nullable(),
facebook: (s: z.ZodString) => s.nullable(),
instagram: (s: z.ZodString) => s.nullable(),
}).omit({ orgType: true });
export const RegionSelectSchema = createSelectSchema(orgs);

Expand All @@ -139,7 +167,12 @@ export const AOInsertSchema = createInsertSchema(orgs, {
.number({ message: "Must have a parent" })
.nonnegative({ message: "Invalid selection" }),
email: (s: z.ZodString) =>
s.email({ message: "Invalid email format" }).or(z.literal("")),
s.email({ message: "Invalid email format" }).or(z.literal("")).nullable(),
description: (s: z.ZodString) => s.nullable(),
website: (s: z.ZodString) => s.nullable(),
twitter: (s: z.ZodString) => s.nullable(),
facebook: (s: z.ZodString) => s.nullable(),
instagram: (s: z.ZodString) => s.nullable(),
}).omit({ orgType: true });
export const AOSelectSchema = createSelectSchema(orgs);

Expand All @@ -148,9 +181,15 @@ export const OrgInsertSchema = createInsertSchema(orgs, {
name: (s: z.ZodString) => s.min(1, { message: "Name is required" }),
parentId: z
.number({ message: "Must have a parent" })
.nonnegative({ message: "Invalid selection" }),
.nonnegative({ message: "Invalid selection" })
.nullable(),
description: (s: z.ZodString) => s.nullable(),
email: (s: z.ZodString) =>
s.email({ message: "Invalid email format" }).or(z.literal("")),
s.email({ message: "Invalid email format" }).or(z.literal("")).nullable(),
website: (s: z.ZodString) => s.nullable(),
twitter: (s: z.ZodString) => s.nullable(),
facebook: (s: z.ZodString) => s.nullable(),
instagram: (s: z.ZodString) => s.nullable(),
});
export const OrgSelectSchema = createSelectSchema(orgs);

Expand Down Expand Up @@ -258,6 +297,51 @@ export const DeleteRequestResponseSchema = z.object({

export type DeleteRequestResponse = z.infer<typeof DeleteRequestResponseSchema>;

// SLACK SCHEMA
export const CustomFieldSchema = z.object({
name: z.string(),
type: z.enum(["text", "select", "multi_select", "user_select"]),
options: z.array(z.string()).optional(),
enabled: z.boolean(),
});

export const SlackSettingsSchema = z.object({
welcome_dm_enable: z.boolean().optional(),
welcome_dm_template: z.string().optional(),
welcome_channel_enable: z.boolean().optional(),
welcome_channel: z.string().optional(),
editing_locked: z.boolean().optional(),
default_backblast_destination: z.string().optional(),
backblast_destination_channel: z.string().optional(),
default_preblast_destination: z.string().optional(),
preblast_destination_channel: z.string().optional(),
backblast_moleskin_template: z.string().optional(),
preblast_moleskin_template: z.string().optional(),
strava_enabled: z.boolean().optional(),
preblast_reminder_days: z.number().optional(),
backblast_reminder_days: z.number().optional(),
automated_preblast_option: z.string().optional(),
automated_preblast_hour_cst: z.number().optional(),
custom_fields: z.array(CustomFieldSchema).optional(),
});

export const SlackSpaceSelectSchema = createSelectSchema(slackSpaces);
export const SlackSpaceInsertSchema = createInsertSchema(slackSpaces);

export const SlackUserSelectSchema = createSelectSchema(slackUsers);
export const SlackUserInsertSchema = createInsertSchema(slackUsers);

export const SlackUserUpsertSchema = z.object({
slackId: z.string(),
userName: z.string(),
email: z.string().email().optional(),
teamId: z.string(),
userId: z.number().optional(),
isAdmin: z.boolean().default(false),
isOwner: z.boolean().default(false),
isBot: z.boolean().default(false),
});

// POSITION SCHEMA
import { positions, positionsXOrgsXUsers } from "@acme/db/schema/schema";

Expand Down