DEV Community

Cover image for Day 9 - Kicking Off Sprint 1 – Authentication, Workspaces, and Case Management
Nader Fkih Hassen
Nader Fkih Hassen

Posted on

Day 9 - Kicking Off Sprint 1 – Authentication, Workspaces, and Case Management

We officially started Sprint 1 of building our Lawyer Management System, Lura. After the planning sessions and backlog setup, it was finally time to get our hands dirty with code.

🛠️ Goals of Sprint 1:
Sprint 1 was focused on building the foundational features of the app:

  1. Magic Link Authentication
  2. Workspace Management
  3. Case Management (CRUD operations)

We broke down the sprint into clear user stories, each mapped to GitHub issues and prioritized in the backlog. With a sprint goal defined, we started implementing the structure piece by piece.

🔐 Magic Link Authentication with Clerk (or NextAuth + custom logic)
For our authentication, we chose a Magic Link method. Unlike traditional username/password logins, Magic Link provides a secure, frictionless login flow using one-time login links via email. This is a huge UX win for business-facing apps like Lura.

Key steps involved:

  • Setup of the authentication service (we opted for Clerk, but this can be replicated with Supabase Auth or custom NextAuth flow).
  • Integration in the Next.js frontend using clerkProvider and session handling via hooks.
  • Restricting access to protected routes using middleware and server-side guards.
// Example: Protecting a page in Next.js
import { useUser } from "@clerk/nextjs";

export default function Dashboard() {
  const { isSignedIn, user } = useUser();
  if (!isSignedIn) return <SignIn />;
  return <div>Welcome {user.firstName}</div>;
}
Enter fullscreen mode Exit fullscreen mode

We also wrote a role-checking helper that can be reused across the app, ensuring that each user only accesses the areas and actions permitted by their role.

🧱 Workspace Creation and Management
Each lawyer/admin should operate within a defined workspace, similar to how Slack or Notion handles organizations.

Technically:

  • We created a Workspace model in Prisma.
  • Related it with a UserWorkspace join table to manage multi-user access.
  • Added basic CRUD API routes using NestJS controllers and services.
  • Built the UI in Next.js with a responsive workspace creation modal.
model Workspace {
  id         String      @id @default(cuid())
  name       String
  createdAt  DateTime    @default(now())
  users      UserWorkspace[]
  cases      Case[]
}
Enter fullscreen mode Exit fullscreen mode

📂 Case Management
Cases are the core of Lura — each case lives inside a workspace and can contain documents, tags, and comments.

We defined a Case model and linked it to both Workspace and User.

Key features:

  • Create / Read / Update / Delete (CRUD) endpoints in NestJS.
  • Route protection using guards for role-based permissions.
  • UI built with TailwindCSS and Next.js dynamic routes.
  • Cases are displayed in a sidebar for easy navigation.

Example:

ts
@Get(':workspaceId/cases')
@UseGuards(AuthGuard)
findCases(@Param('workspaceId') id: string) {
  return this.caseService.findByWorkspace(id);
}
Enter fullscreen mode Exit fullscreen mode

🤖 Technical Stack Overview

  • Frontend: Next.js + TailwindCSS
  • Backend: NestJS
  • ORM: Prisma
  • DB: PostgreSQL
  • Auth: Magic Link (via Clerk/Supabase/NextAuth)
  • Hosting: Vercel (Frontend) + Render or Railway (Backend)

✅ Takeaways

  • Planning ahead made implementation smoother — especially for auth and data relations.
  • Prisma made defining models and relations very intuitive.
  • Integrating both frontend and backend from the start helped ensure alignment in data structures.
  • Role-based access is tricky but essential — we began building a permission service early to avoid security gaps.

❓Questions for You:

  • How do you structure role-based access in your apps?
  • Do you start with auth or database models first?

Top comments (0)