Skip to content

Commit

Permalink
feat(envited.ascs.digital): Save member categories (#118)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeroenbranje authored Mar 1, 2024
2 parents b96d09e + a1d6ea5 commit 2ac43d0
Show file tree
Hide file tree
Showing 19 changed files with 940 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface CheckboxItem {

interface CheckboxProps {
name: string
values: []
values: string[]
label: string | ReactElement<any, string | JSXElementConstructor<any>>
description?: string
error?: string
Expand Down
4 changes: 2 additions & 2 deletions apps/envited.ascs.digital/app/dashboard/profile/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { Profile } from '../../../modules/Profile'

export default async function Index() {
const profile = await getProfile('testcompany-gmbh')
const memberCategories = await getBusinessCategories()
const businessCategories = await getBusinessCategories()

return <Profile profile={profile} memberCategories={memberCategories} />
return <Profile profile={profile} businessCategories={businessCategories} />
}

export const dynamic = 'force-dynamic'
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
import { businessCategory } from '../schema'
import { eq } from 'drizzle-orm'

import { businessCategory, profilesToBusinessCategories } from '../schema'
import { DatabaseConnection } from '../types'

export const getBusinessCategories = (db: DatabaseConnection) => async () => db.select().from(businessCategory)

export const getBusinessCategoriesByProfileId = (db: DatabaseConnection) => async (profileId: string) =>
db
.select({ businessCategoryId: profilesToBusinessCategories.businessCategoryId })
.from(profilesToBusinessCategories)
.where(eq(profilesToBusinessCategories.profileId, profileId))

export const insertBusinessCategoryByProfileId =
(db: DatabaseConnection) => async (profileId: string, businessCategoryId: string) =>
db.insert(profilesToBusinessCategories).values({
profileId,
businessCategoryId,
})

export const deleteBusinessCategoriesByProfileId = (db: DatabaseConnection) => async (profileId: string) =>
db.delete(profilesToBusinessCategories).where(eq(profilesToBusinessCategories.profileId, profileId))
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ export const maybeUpdatePublishedState = (db: DatabaseConnection) => async (data
}

export const getProfileBySlug = (db: DatabaseConnection) => async (slug: string) =>
db.select().from(profile).where(eq(profile.slug, slug))
db.query.profile.findFirst({
where: eq(profile.slug, slug),
with: {
businessCategories: true,
},
})

export const getPublishedProfiles = (db: DatabaseConnection) => async () =>
db.select().from(profile).where(eq(profile.isPublished, true))
12 changes: 10 additions & 2 deletions apps/envited.ascs.digital/common/database/queries/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import { fromPairs, map, pipe, toPairs } from 'ramda'

import { connectDb } from '../database'
import * as schema from '../schema'
import { getBusinessCategories } from './businessCategories'
import {
deleteBusinessCategoriesByProfileId,
getBusinessCategories,
getBusinessCategoriesByProfileId,
insertBusinessCategoryByProfileId,
} from './businessCategories'
import { fetchTables } from './common'
import { getProfileBySlug, getPublishedProfiles, maybeUpdatePublishedState, update as updateProfile } from './profiles'
import {
Expand All @@ -18,11 +23,14 @@ import {

const queries = {
deleteUserById,
deleteBusinessCategoriesByProfileId,
fetchTables,
getBusinessCategories,
getBusinessCategoriesByProfileId,
getUserById,
getUserWithProfileById,
getUsersByIssuerId,
insertBusinessCategoryByProfileId,
insertUserTx,
updateProfile,
maybeUpdatePublishedState,
Expand All @@ -38,7 +46,7 @@ export const init =
string,
(
db: PostgresJsDatabase<typeof schema>,
) => (...args: any[]) => Promise<postgres.RowList<Record<string, unknown>[]> | postgres.Row>
) => (...args: any[]) => Promise<postgres.RowList<Record<string, unknown>[]> | postgres.Row | undefined>
>,
) =>
async () => {
Expand Down
8 changes: 8 additions & 0 deletions apps/envited.ascs.digital/common/database/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ export const profile = pgTable('profile', {
updatedAt: timestamp('updated_at'),
})

export const profileRelations = relations(profile, ({ many }) => ({
businessCategories: many(profilesToBusinessCategories),
}))

export const businessCategory = pgTable('businessCategory', {
id: text('id').unique().primaryKey(),
name: text('name').unique(),
Expand All @@ -146,6 +150,10 @@ export const businessCategory = pgTable('businessCategory', {
updatedAt: timestamp('updated_at'),
})

export const businessCategoryRelations = relations(businessCategory, ({ many }) => ({
profilesToBusinessCategories: many(profilesToBusinessCategories),
}))

export const profilesToBusinessCategories = pgTable('profilesToBusinessCategories', {
profileId: uuid('profile_id')
.references(() => profile.id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,25 @@ export const _get =
}

export const get = _get({ db, getServerSession, log })

export const _getProfileBusinessCategories =
({ db, getServerSession, log }: { db: Database; getServerSession: () => Promise<Session | null>; log: Log }) =>
async (profileId: string) => {
try {
const session = await getServerSession()

if (isNil(session)) {
throw unauthorizedError({ resource: 'businessCategories' })
}

const connection = await db()
const categories = await connection.getBusinessCategoriesByProfileId(profileId)

return categories
} catch (error: unknown) {
log.error(formatError(error))
throw internalServerErrorError()
}
}

export const getProfileBusinessCategories = _getProfileBusinessCategories({ db, getServerSession, log })
36 changes: 15 additions & 21 deletions apps/envited.ascs.digital/common/serverActions/profiles/get.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,11 @@ describe('serverActions/profiles/get', () => {
})

const dbStub = jest.fn().mockResolvedValue({
getProfileBySlug: jest.fn().mockResolvedValue([
{
name: 'USER_PRINCIPAL_NAME',
description: 'USER_DESCRIPTION',
principalName: 'USER_PRINCIPAL_NAME',
},
]),
getProfileBySlug: jest.fn().mockResolvedValue({
name: 'USER_PRINCIPAL_NAME',
description: 'USER_DESCRIPTION',
principalName: 'USER_PRINCIPAL_NAME',
}),
getUserById: jest.fn().mockResolvedValue([
{
name: 'USER_PRINCIPAL_NAME',
Expand Down Expand Up @@ -63,13 +61,11 @@ describe('serverActions/profiles/get', () => {
})

const dbStub = jest.fn().mockResolvedValue({
getProfileBySlug: jest.fn().mockResolvedValue([
{
name: 'USER_PRINCIPAL_NAME',
description: 'USER_DESCRIPTION',
principalName: 'USER_PRINCIPAL_NAME',
},
]),
getProfileBySlug: jest.fn().mockResolvedValue({
name: 'USER_PRINCIPAL_NAME',
description: 'USER_DESCRIPTION',
principalName: 'USER_PRINCIPAL_NAME',
}),
getUserById: jest.fn().mockResolvedValue([
{
name: 'USER_NAME',
Expand Down Expand Up @@ -106,13 +102,11 @@ describe('serverActions/profiles/get', () => {
const getServerSessionStub = jest.fn().mockResolvedValue(null)

const dbStub = jest.fn().mockResolvedValue({
getProfileBySlug: jest.fn().mockResolvedValue([
{
name: 'USER_NAME',
description: 'USER_DESCRIPTION',
principalName: 'USER_PRINCIPAL_NAME',
},
]),
getProfileBySlug: jest.fn().mockResolvedValue({
name: 'USER_NAME',
description: 'USER_DESCRIPTION',
principalName: 'USER_PRINCIPAL_NAME',
}),
getUserById: jest.fn().mockResolvedValue([
{
name: 'USER_NAME',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Database } from '../../database/types'
import { isOwnProfile, isUsersCompanyProfile } from '../../guards'
import { Log, log } from '../../logger'
import { Session } from '../../types'
import { badRequestError, formatError, internalServerErrorError, notFoundError, unauthorizedError } from '../../utils'
import { badRequestError, formatError, internalServerErrorError, notFoundError } from '../../utils'

export const _get =
({ db, getServerSession, log }: { db: Database; getServerSession: () => Promise<Session | null>; log: Log }) =>
Expand All @@ -21,7 +21,7 @@ export const _get =

const session = await getServerSession()
const connection = await db()
const [profile] = await connection.getProfileBySlug(slug)
const profile = await connection.getProfileBySlug(slug)

if (isNil(profile) || isEmpty(profile)) {
throw notFoundError({ resource: 'profiles', resourceId: slug, userId: session?.user.id })
Expand Down
14 changes: 12 additions & 2 deletions apps/envited.ascs.digital/common/serverActions/profiles/update.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use server'

import { isNil } from 'ramda'
import { dissoc, isNil } from 'ramda'

import { getServerSession } from '../../auth'
import { db } from '../../database/queries'
Expand All @@ -12,7 +12,7 @@ import { badRequestError, forbiddenError, formatError, internalServerErrorError,

export const _update =
({ db, getServerSession, log }: { db: Database; getServerSession: () => Promise<Session | null>; log: Log }) =>
async (profile: Partial<Profile>) => {
async (profile: Partial<Profile>, businessCategories?: string[]) => {
try {
const session = await getServerSession()
if (isNil(session)) {
Expand Down Expand Up @@ -50,6 +50,16 @@ export const _update =
}

const [updatedProfile] = await connection.updateProfile(profile)

if (businessCategories) {
await connection.deleteBusinessCategoriesByProfileId(updatedProfile.id)

const insertProfilesToBusinessCategoriesPromises = businessCategories.map((id: string) =>
connection.insertBusinessCategoryByProfileId(updatedProfile.id, id),
)

await Promise.all(insertProfilesToBusinessCategoriesPromises)
}
const [result] = await connection.maybeUpdatePublishedState(updatedProfile)
return result
} catch (error: unknown) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
ALTER TABLE "profile" DROP CONSTRAINT "profile_name_user_name_fk";
--> statement-breakpoint
ALTER TABLE "profilesToBusinessCategories" DROP CONSTRAINT "profilesToBusinessCategories_profile_id_profile_id_fk";
--> statement-breakpoint
ALTER TABLE "user" DROP CONSTRAINT "user_issuer_id_issuer_id_fk";
--> statement-breakpoint
ALTER TABLE "usersToCredentialTypes" DROP CONSTRAINT "usersToCredentialTypes_user_id_user_id_fk";
--> statement-breakpoint
ALTER TABLE "usersToRoles" DROP CONSTRAINT "usersToRoles_user_id_user_id_fk";
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "profile" ADD CONSTRAINT "profile_name_user_name_fk" FOREIGN KEY ("name") REFERENCES "user"("name") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "profilesToBusinessCategories" ADD CONSTRAINT "profilesToBusinessCategories_profile_id_profile_id_fk" FOREIGN KEY ("profile_id") REFERENCES "profile"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "user" ADD CONSTRAINT "user_issuer_id_issuer_id_fk" FOREIGN KEY ("issuer_id") REFERENCES "issuer"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "usersToCredentialTypes" ADD CONSTRAINT "usersToCredentialTypes_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "usersToRoles" ADD CONSTRAINT "usersToRoles_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
Loading

0 comments on commit 2ac43d0

Please sign in to comment.