Skip to content

Commit

Permalink
feature: tenancy
Browse files Browse the repository at this point in the history
  • Loading branch information
geclos committed Jul 22, 2024
1 parent 11e7b66 commit 44c16cf
Show file tree
Hide file tree
Showing 34 changed files with 462 additions and 395 deletions.
7 changes: 5 additions & 2 deletions apps/web/src/actions/documents/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ export const createDocumentVersionAction = withProject
}),
{ type: 'json' },
)
.handler(async ({ input }) => {
const result = await createDocumentVersion(input)
.handler(async ({ input, ctx }) => {
const result = await createDocumentVersion({
...input,
project: ctx.project,
})
return result.unwrap()
})
10 changes: 5 additions & 5 deletions apps/web/src/actions/procedures/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { findProject } from '@latitude-data/core'
import { ProjectsRepository } from '@latitude-data/core'
import { getCurrentUser } from '$/services/auth/getCurrentUser'
import { z } from 'zod'
import { createServerActionProcedure } from 'zsa'
Expand All @@ -16,11 +16,11 @@ export const authProcedure = createServerActionProcedure().handler(async () => {
export const withProject = createServerActionProcedure(authProcedure)
.input(z.object({ projectId: z.number() }))
.handler(async ({ input, ctx }) => {
const { workspace } = ctx
const projectScope = new ProjectsRepository(workspace.id)
const project = (
await findProject({
projectId: input.projectId,
workspaceId: ctx.workspace.id,
})
await projectScope.getProjectById(input.projectId)
).unwrap()

return { ...ctx, project }
})
1 change: 0 additions & 1 deletion apps/web/src/actions/user/setupAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export const setupAction = createServerAction()
)
.handler(async ({ input }) => {
const itWasAlreadySetup = await isWorkspaceCreated()

if (itWasAlreadySetup) {
throw new Error('Workspace already created')
}
Expand Down
30 changes: 20 additions & 10 deletions apps/web/src/app/(private)/_data-access/index.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,44 @@
import { cache } from 'react'

import {
findCommit as originalfindCommit,
findProject as originalFindProject,
getFirstProject as originalGetFirstProject,
type FindCommitProps,
type FindProjectProps,
CommitsRepository,
Project,
ProjectsRepository,
} from '@latitude-data/core'

export const getFirstProject = cache(
async ({ workspaceId }: { workspaceId: number }) => {
const result = await originalGetFirstProject({ workspaceId })
const projectsScope = new ProjectsRepository(workspaceId)
const result = await projectsScope.getFirstProject()
const project = result.unwrap()

return project
},
)

export const findProject = cache(
async ({ projectId, workspaceId }: FindProjectProps) => {
const result = await originalFindProject({ projectId, workspaceId })
async ({
projectId,
workspaceId,
}: {
projectId: number
workspaceId: number
}) => {
const projectsScope = new ProjectsRepository(workspaceId)
const result = await projectsScope.getProjectById(projectId)
const project = result.unwrap()

return project
},
)

export const findCommit = cache(
async ({ uuid, projectId }: FindCommitProps) => {
const result = await originalfindCommit({ uuid, projectId })
async ({ uuid, project }: { uuid: string; project: Project }) => {
const commitsScope = new CommitsRepository(project.workspaceId)
const result = await commitsScope.getCommitByUuid({
projectId: project.id,
uuid,
})
const commit = result.unwrap()

return commit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('GET documentVersion', () => {
commit,
})

await mergeCommit({ commitId: commit.id })
await mergeCommit(commit)

const response = await GET(
new NextRequest(
Expand All @@ -41,7 +41,7 @@ describe('GET documentVersion', () => {
commit,
})

await mergeCommit({ commitId: commit.id })
await mergeCommit(commit)

const response = await GET(
new NextRequest(
Expand All @@ -64,7 +64,7 @@ describe('GET documentVersion', () => {
const { project } = await ctx.factories.createProject()
const { commit } = await ctx.factories.createDraft({ project })

await mergeCommit({ commitId: commit.id })
await mergeCommit(commit)

const response = await GET(
new NextRequest(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { getDocumentByPath } from '@latitude-data/core'
import { DocumentVersionsRepository } from '@latitude-data/core'
import apiRoute from '$/helpers/api/route'
import { NextRequest } from 'next/server'
import { LatitudeRequest } from '$/middleware'

export async function GET(
_: NextRequest,
req: LatitudeRequest,
{
params,
}: {
Expand All @@ -15,11 +15,12 @@ export async function GET(
},
) {
return apiRoute(async () => {
const workspaceId = req.workspaceId!
const { projectId, commitUuid, documentPath } = params

const result = await getDocumentByPath({
projectId: Number(projectId),
const documentVersionsScope = new DocumentVersionsRepository(workspaceId)
const result = await documentVersionsScope.getDocumentByPath({
commitUuid,
projectId: Number(projectId),
path: documentPath.join('/'),
})
const document = result.unwrap()
Expand Down
4 changes: 3 additions & 1 deletion apps/web/src/app/(private)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ export default async function AppRoot() {
try {
session = await getCurrentUser()
project = await getFirstProject({ workspaceId: session.workspace.id })
await findCommit({ uuid: HEAD_COMMIT, projectId: project.id })

await findCommit({ uuid: HEAD_COMMIT, project })

url = PROJECT_ROUTE({ id: project.id }).commits.latest
} catch (error) {
if (error instanceof NotFoundError) {
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/app/(private)/projects/[projectId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ export default async function ProjectPage({ params }: ProjectPageParams) {
try {
session = await getCurrentUser()
project = await findProject({
projectId: params.projectId,
projectId: Number(params.projectId),
workspaceId: session.workspace.id,
})
await findCommit({ uuid: HEAD_COMMIT, projectId: project.id })
await findCommit({ uuid: HEAD_COMMIT, project })
url = PROJECT_ROUTE({ id: +project.id }).commits.latest
} catch (error) {
if (error instanceof NotFoundError) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import { ReactNode } from 'react'

import {
Commit,
CommitsRepository,
HEAD_COMMIT,
NotFoundError,
Project,
ProjectsRepository,
} from '@latitude-data/core'
import { CommitProvider, ProjectProvider } from '@latitude-data/web-ui'
import { AppLayout, BreadcrumpBadge } from '@latitude-data/web-ui/browser'
import { findCommit, findProject } from '$/app/(private)/_data-access'
import { NAV_LINKS } from '$/app/(private)/_lib/constants'
import { ProjectPageParams } from '$/app/(private)/projects/[projectId]/page'
import { getCurrentUser, SessionData } from '$/services/auth/getCurrentUser'
Expand All @@ -29,18 +30,20 @@ export default async function CommitLayout({
let commit: Commit
try {
session = await getCurrentUser()
project = await findProject({
projectId: params.projectId,
workspaceId: session.workspace.id,
})
commit = await findCommit({
uuid: params.commitUuid,
projectId: project.id,
})
const projectsRepo = new ProjectsRepository(session.workspace.id)
const commitsRepo = new CommitsRepository(session.workspace.id)
project = (
await projectsRepo.getProjectById(Number(params.projectId))
).unwrap()
commit = (
await commitsRepo.getCommitByUuid({
uuid: params.commitUuid,
projectId: project.id,
})
).unwrap()
} catch (error) {
if (error instanceof NotFoundError) {
return notFound()
}
if (error instanceof NotFoundError) return notFound()

throw error
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { getDocumentsAtCommit } from '@latitude-data/core'
import { NextRequest, NextResponse } from 'next/server'
import { DocumentVersionsRepository } from '@latitude-data/core'
import { LatitudeRequest } from '$/middleware'
import { NextResponse } from 'next/server'

export async function GET(
_: NextRequest,
req: LatitudeRequest,
{
params: { commitUuid, projectId },
}: { params: { commitUuid: string; projectId: number } },
) {
try {
const documents = await getDocumentsAtCommit({
const workspaceId = req.workspaceId!
const scope = new DocumentVersionsRepository(workspaceId)
const documents = await scope.getDocumentsAtCommit({
commitUuid,
projectId: Number(projectId),
})
Expand Down
13 changes: 8 additions & 5 deletions apps/web/src/components/Sidebar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import { getDocumentsAtCommit } from '@latitude-data/core'
import { DocumentVersionsRepository, Project } from '@latitude-data/core'

import DocumentTree, { CreateNode } from './DocumentTree'

export default async function Sidebar({
commitUuid,
projectId,
project,
}: {
commitUuid: string
projectId: number
project: Project
}) {
const documentsResult = await getDocumentsAtCommit({
projectId,
const documentVersionsScope = new DocumentVersionsRepository(
project.workspaceId,
)
const documentsResult = await documentVersionsScope.getDocumentsAtCommit({
projectId: project.id,
commitUuid,
})
const documents = documentsResult.unwrap()
Expand Down
7 changes: 2 additions & 5 deletions apps/web/src/data-access/users.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
database,
getUser,
unsafelyGetUser,
NotFoundError,
Result,
users,
Expand Down Expand Up @@ -31,15 +31,12 @@ export async function getUserFromCredentials({
},
where: eq(users.email, email),
})

if (!user) return notFound()

const validPassword = await verifyPassword(password, user.encryptedPassword)

if (!validPassword) notFound()

const wpResult = await getWorkspace({ userId: user.id })

if (wpResult.error) {
return Result.error(wpResult.error)
}
Expand All @@ -60,7 +57,7 @@ export async function getCurrentUserFromDB({
}: {
userId: string | undefined
}): PromisedResult<SessionData, NotFoundError> {
const user = await getUser(userId)
const user = await unsafelyGetUser(userId)
if (!user) return notFound()

const wpResult = await getWorkspace({ userId: user.id })
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getApiKey } from '@latitude-data/core'
import { unsafelyGetApiKey } from '@latitude-data/core'
import { NextRequest, NextResponse } from 'next/server'

import env from './env'
Expand All @@ -15,7 +15,7 @@ export async function middleware(request: LatitudeRequest) {
return apiUnauthorized()
}

const result = await getApiKey({ uuid: token })
const result = await unsafelyGetApiKey({ uuid: token })
if (result.error) return apiUnauthorized()

request.workspaceId = result.value.workspaceId
Expand Down
9 changes: 7 additions & 2 deletions packages/core/src/data-access/apiKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@ import { NotFoundError, Result } from '$core/lib'
import { apiKeys } from '$core/schema'
import { eq } from 'drizzle-orm'

export async function getApiKey({ uuid }: { uuid: string }, db = database) {
const apiKey = await db.query.apiKeys.findFirst({ where: eq(apiKeys, uuid) })
export async function unsafelyGetApiKey(
{ uuid }: { uuid: string },
db = database,
) {
const apiKey = await db.query.apiKeys.findFirst({
where: eq(apiKeys.uuid, uuid),
})
if (!apiKey) return Result.error(new NotFoundError('API key not found'))

return Result.ok(apiKey)
Expand Down
Loading

0 comments on commit 44c16cf

Please sign in to comment.