Building a Library App with Next.js, PostgreSQL, and More

This text details the creation of a full-stack web application for a university library. The application features user authentication, book browsing, and borrowing functionality. The backend uses PostgreSQL with Neon for a serverless database and Drizzle ORM for efficient data management. Frontend technologies include Next.js, Shadcn UI, and Tailwind CSS. Additional services integrated are Upstash for caching and workflows, ImageKit for asset management, and Resend for email delivery. The development process is described step-by-step, highlighting best practices and problem-solving.

University Library App Study Guide

Quiz

Instructions: Answer the following questions in 2-3 sentences each.

  1. What is the purpose of using Tailwind CSS in this application?
  2. Explain the role of shaten/ui in the app’s development.
  3. What is Neon and how is it utilized in this project?
  4. What is an ORM, and why is Drizzle chosen for this application?
  5. What is the function of Upstash Redis in the app’s architecture?
  6. Describe the purpose of Upstash Workflows within this project?
  7. Why is rate limiting implemented in the authentication process, and how does Upstash facilitate this?
  8. How are emails sent using Resend, and why is this tool chosen?
  9. Explain the functionality of the Imagekit service in this application.
  10. Describe the purpose of the borrowing functionality and the database interaction associated with it.

Quiz Answer Key

  1. Tailwind CSS provides a way to style the application with full flexibility, using pre-defined utility classes, similar to writing regular CSS, but more quickly and efficiently. It enables a consistent look and feel across all components.
  2. shaten/ui is a library that provides pre-built components, like buttons or forms, that can be easily customized using Tailwind CSS. These components allow for quicker development and standardization of the app’s interface.
  3. Neon is a serverless PostgreSQL database that provides instant provisioning and easy integration with the project’s stack. It simplifies the process of using a PostgreSQL database by removing the need for complicated configurations.
  4. An ORM (Object-Relational Mapping) is a tool that allows developers to interact with databases using objects, rather than writing SQL queries. Drizzle was chosen because it is designed for modern TypeScript developers, offering type safety and easy use.
  5. Upstash Redis provides low-latency data storage and retrieval, which is ideal for tasks like caching, session management, and real-time data needs. In the app, it is used to fetch books quickly and implement rate limiting.
  6. Upstash Workflows enables the automation of multi-step tasks, such as onboarding new users or managing data processing. In this app, it is used to automatically send emails, check user inactivity, and manage book borrowing deadlines.
  7. Rate limiting prevents DDOS attacks by restricting the number of requests a user can make in a given timeframe. Upstash Redis is used to keep track of requests and enforce the limit.
  8. Emails are sent using Resend, a tool that allows for customized email templates using React components. It is used in this application for sending welcome emails and reminders to users who have been inactive.
  9. Imagekit is a tool that enables the optimization and transformation of images and videos, providing a central hub for efficiently managing assets. It allows for faster load times and easy management of visual content.
  10. The borrowing functionality allows users to borrow a book, which initiates a database mutation for tracking purposes. This also uses a newly created “borrow records” table which tracks which users borrowed which books, when they borrowed them and when their return date is.

Essay Questions

Instructions: Answer each question in a multi-paragraph essay format.

  1. Discuss the importance of using a modern tech stack when developing web applications. How does the specific stack used in this library app contribute to its scalability, maintainability, and performance?
  2. Analyze the role of serverless technologies in the development of the University Library app. How does the use of Neon, Upstash, and Vercel contribute to the app’s overall architecture and operational efficiency?
  3. Compare and contrast using an ORM such as Drizzle with using native SQL for database interactions. What are the advantages and disadvantages of each approach for this specific project?
  4. Explain the importance of both client-side and server-side components in Next.js applications. How does the architecture of the University Library app utilize these components and balance the benefits of server-side rendering with client interactivity?
  5. Describe the processes for implementing both authentication and authorization in this project. How are server actions used to manage user data and maintain data security?

Glossary of Key Terms

API (Application Programming Interface): A set of rules and protocols that allows different software applications to communicate with each other.

bcrypt: A password hashing function used to securely store passwords in a database.

Caching: The process of storing frequently accessed data in a temporary storage location to improve retrieval speed.

CSS (Cascading Style Sheets): A style sheet language used for describing the look and formatting of a document written in a markup language.

DDOS (Distributed Denial of Service) Attack: A cyberattack in which the perpetrator seeks to make a machine or network resource unavailable to its intended users by temporarily or indefinitely disrupting services.

Drizzle: An open-source ORM (Object-Relational Mapping) designed for modern TypeScript developers.

ESLint: A tool for identifying and reporting patterns found in ECMAScript/JavaScript code.

Imagekit: A free tool for quickly optimizing and transforming videos and images.

JWT (JSON Web Token): A standard for securely transmitting information between parties as a JSON object.

Neon: A serverless PostgreSQL database service.

Next.js: A React framework for building web applications, enabling server-side rendering and other performance optimizations.

ORM (Object-Relational Mapping): A technique that lets you query and manipulate data from a database using an object-oriented paradigm.

Prettier: A code formatter used to ensure consistent code style and readability.

Rate Limiting: A technique used to limit the number of requests a user can make within a specific time frame.

Redis: An open source, in-memory data structure store, used as a database, cache, message broker, and streaming engine.

Resend: A service that provides APIs for sending transactional emails.

Shaten UI: A library of customizable components that can be easily integrated into a Tailwind CSS project.

SQL (Structured Query Language): A domain-specific language used in programming and designed for managing data held in a relational database management system.

Tailwind CSS: A utility-first CSS framework that allows for rapid styling of web applications.

TypeScript: A superset of JavaScript that adds static typing to the language.

Upstash: A serverless data platform offering a variety of services including Redis, Workflows and Vectors.

Vercel: A cloud platform for frontend developers that allows for serverless deployment of web applications.

University Library Application Development

Okay, here is a detailed briefing document summarizing the provided source:

Briefing Document: University Library Application Development

Overview:

This document summarizes the development process of a University Library application, focusing on the technologies, features, and key decisions involved in its creation. The project emphasizes building a scalable, production-ready application using industry-standard, open-source tools. The approach includes detailed explanations and demonstrations, aiming to teach not just replication of the specific application, but the broader use of these technologies for future projects.

Key Themes & Technologies:

  1. Modern Frontend Development:
  • Next.js: Chosen as the core framework for the application, offering features like server-side rendering and an app router for a smoother user experience.
  • “Next JS will now automatically install all of the dev dependencies needed for us to run our project very easily”
  • TypeScript: Used to ensure a well-structured and maintainable codebase, with a commitment to explaining its usage for newcomers.
  • “I’ll later explain the many benefits you’re getting by using typescript and and don’t worry if you haven’t used tab script before”
  • Tailwind CSS: Selected for styling applications due to its flexibility and utility-first approach.
  • “It allows you to have full flexibility of how your applications are going to look like it’s just like you’re writing Reg CSS you have all the properties at your disposal but you can use them in a quicker way by simply using a set of predefined utility classes”
  • Shadcn UI: A component library that provides pre-built components styled with Tailwind CSS, enhancing the visual consistency and standardization of the application.
  • “a library that allows you to copy some of the components but then use the full power of Tailwind CSS to style them to your liking”
  • Prettier and ESLint: Utilized to maintain code cleanliness and enforce best practices, ensuring a scalable and well-maintained codebase.
  • “we want our codebase to be scalable well structured and maintained”
  1. Robust Backend & Database:
  • PostgreSQL: Chosen as the database for its advanced capabilities and open-source nature, managed with Neon for ease of use.
  • Neon: Provides a serverless PostgreSQL database with features like instant provisioning and integration with Next.js, simplifying the setup and scaling process.
  • “It allows you to use open- Source postgress databases with many features that make it such a breeze to use you get instant provisioning no waiting no config and it configures directly with your stack”
  • Drizzle ORM: Implemented to make database architecture scalable and production-ready by simplifying database interactions with its type-safe and easy-to-use design.
  • “an object relational mapping tool which will allow you to make your database architecture that much more scalable and drizzle is definitely the way to go nowadays”
  1. Asset Management & Optimization:
  • ImageKit: A free tool used for optimizing and managing images and videos within the application, ensuring efficient media handling.
  • “It is a free tool allowing you to quickly optimize and transform your videos and images and just have a central Hub where you can efficiently manage all of the assets for your project”
  1. Advanced Features for Production Readiness:
  • Upstash Redis: Used for low-latency data storage and retrieval, beneficial for caching, session management, and real-time applications.
  • “a service that offers low latency data storage and retrieval perfect for caching session management and real-time applications”
  • Upstash Workflows: Employed to manage and automate multi-step tasks such as onboarding, data processing, email notifications, and user activity tracking.
  • “allowing you to manage and automate multi-step tasks great for things like onboarding or handling data processing workflow flows”
  • Rate Limiting: Implemented using Upstash to prevent denial-of-service attacks and ensure fair usage of the application.
  1. User Experience and Authentication:
  • Next-Auth (Oauth): Used for handling user authentication, employing a credentials provider for custom email/password login logic.
  • “import next OD we get a lot of things out of it like the signin functionality sign out off and more and we can choose which providers to add”
  • Custom Email Templates: Resend is used for sending emails, allowing the use of React components for custom email templates, enhancing the design and customization options.
  • “you can completely write your email templates using react components that is not possible with simpler tools like email JS”

Key Features Demonstrated:

  • User Authentication: Full sign-up and sign-in flows with validation, including image uploads.
  • “when you visit the website for the first time you’ll see the signin screen if you’re creating a new account you can go to the signup page where you’ll have to fill in a lot of information all of it fully validated we also have an image upload with completion percentage”
  • Automated Workflows: Onboarding processes such as welcome emails, inactivity checks, and notifications.
  • “the moment you’ve created an account our server triggered an onboarding workflow sending you a welcome email but that’s not the best part another part of the onboarding workflow is inactivity checks so if you don’t visit the website for the next 3 days you’ll get another automated email prompting you to check it out”
  • Book Management: Displaying detailed book information, including descriptions, author, copies, and videos, with filtering, searching, and pagination.
  • “there’s this library page where you can see a full list of books available in the library with pation boort and you can easily search for any book or filter it through your liking and if you click on any of these books you’ll go to its Details page where you can see complete information from Total and available copies description trailers summaries and more”
  • Borrowing System: Implementing a borrowing process with account approval for users, and managing book availability.
  • “if you click on borrow book you’ll see a destructive toast saying you can’t borrow a book until your account gets approved Yep this is what we’re doing we’re not letting just anyone visit the website and try to borrow a book instead we’ll allow admins to approve their account”
  • Rate Limiting: Preventing abuse and ensuring stable service availability.

Important Ideas and Facts:

  • Emphasis on Industry Standards: The project is built using technologies and practices commonly found in production environments.
  • Practical Learning: The approach prioritizes understanding how to build scalable applications, not just replicating this specific project.
  • Serverless Architecture: The utilization of Neon and Upstash for serverless databases, simplifying infrastructure management.
  • Open Source Focus: All tools and technologies utilized are open-source, promoting accessibility and community contributions.
  • Importance of Rate Limiting: Protecting applications against malicious activity with Upstash Redis.
  • Power of Workflows: Automating tasks and user engagement with Upstash Workflows.
  • Customizable Email Templates: Using Resend to send emails with fully customizable design.

Conclusion:

This project demonstrates a comprehensive approach to building a production-ready application using modern technologies and best practices. The emphasis on scalability, automation, and user experience makes it a valuable learning experience for aspiring developers. The detailed explanations provided throughout the project aim to empower users to not only build this application, but also apply the knowledge to their own future projects.

Building a Scalable University Library Application

FAQ: Building a Scalable University Library Application

1. What technologies are used to build this application?

This application leverages a variety of modern, production-ready technologies. For styling, it uses Tailwind CSS for flexibility and utility classes, along with Shadcn UI for pre-built components that are customizable. The database is PostgreSQL, accessed through Neon, which provides a serverless experience. Drizzle ORM is employed for scalable database architecture, and ImageKit manages assets like images and videos. Finally, Upstash Redis is used for caching and workflows. The app is also built using Next.js, Typescript, and ESLint, Prettier.

2. How does user onboarding work in this app?

The application automates the onboarding process. When a user creates an account, a welcome email is sent. The system also includes inactivity checks, triggering automated emails if the user doesn’t visit the website for a few days, or a congratulations email if they are using the app. Account approval by an administrator is required before book borrowing is enabled, similar to university admission processes. This system leverages Upstash’s workflows.

3. What are the benefits of using TypeScript in this project?

TypeScript provides several benefits to this project, such as type checking which helps to catch errors early on in development, and improved code maintainability as the project gets larger. It also provides strong typing when defining the database schemas through drizzle, allowing for more reliable data models.

4. Why is rate limiting important, and how is it implemented in this application?

Rate limiting is crucial for preventing denial-of-service (DDOS) attacks. It restricts the number of requests a user or IP address can make within a specific time frame. In this application, rate limiting is implemented using Upstash Redis. When a user exceeds the limit, they are redirected to a “Too Fast” page.

5. How are emails handled in this application, especially for onboarding and notifications?

Email functionality is handled by Resend. The application uses Resend to send welcome emails upon signup and to notify users if they haven’t been active in a while. These emails are created with react component templates, allowing for fully customized designs. The email logic is set up with Upstash workflows.

6. How are images and videos managed within this application?

Images and videos are managed using ImageKit, which provides a centralized hub to efficiently optimize, transform, and manage assets. This includes features like progress tracking during uploads, file size validation, and rendering optimized assets on the front end of the application.

7. How is the database set up and what role does Drizzle ORM play?

The database is set up using Neon, a serverless Postgres service, which allows for easy provisioning and scaling without complex configurations. Drizzle ORM acts as an object-relational mapping tool, which enables interaction with the database using typesafe, clean, and easy-to-use code. Drizzle allows for database schemas to be defined with JavaScript rather than using raw SQL, which simplifies the development process. Drizzle is also used to generate and manage migrations for SQL databases.

8. How is user authentication implemented, and is there a user role system?

User authentication is implemented using NextAuth.js, with a custom credential provider for email and password. There isn’t the concept of social login with google and github implemented in this specific course. The application includes a basic user role system, with users having a “pending,” “approved,” or “rejected” status, and a role of either “user” or “admin”. Admin roles are required to create new book records in the database. Users also have an activity check, allowing the system to prompt them with emails if they are inactive after a specific period of time.

Full-Stack Library Management System

The sources describe the development of a full-stack library management system. The system consists of two interconnected applications: a public-facing app for users and an admin interface. The apps are built using a monorepo architecture. The development process emphasizes industry-standard practices and real-world application demands.

Key aspects of the app development include:

  • Technology Stack:
  • Next.js with TypeScript for building web applications.
  • Tailwind CSS for styling, along with Shadcn UI for pre-built components.
  • PostgreSQL database, managed with Neon and Drizzle ORM for efficient database interactions.
  • Upstash for caching, rate limiting, and workflow automation using Redis.
  • ImageKit for real-time media processing and asset management.
  • Resend for email communications.
  • Oauth.js for authentication.
  • Public Facing App:
  • Open-source authentication with personalized onboarding flows and emails.
  • Homepage featuring a highlighted book and newly added books with 3D effects.
  • Library page with advanced filtering and pagination.
  • Book detail pages that track availability and show summaries, videos, and similar books.
  • Profile page to manage accounts, track borrowed books, and download receipts.
  • Admin Interface:
  • Analytics dashboard displaying statistics on new users and book borrows.
  • User management including all users and account requests pages where admins can approve or revoke access.
  • Book management pages with forms for adding and editing books and detail pages.
  • Borrow request management.
  • Key Features and Functionality:
  • Rate limiting to protect against DDOS attacks.
  • Caching optimizations for faster data retrieval.
  • Multimedia uploads and management.
  • Advanced error handling.
  • Automated workflows with custom notifications, such as onboarding emails, borrowing deadlines, and reminders.
  • Complex database queries using Drizzle ORM.
  • Image and video optimization using ImageKit.
  • Form validation using React Hook Form and Zod.
  • Server actions for secure server-side operations.
  • Database migrations for managing database schema changes.
  • Development Process:
  • The project started as a simple tutorial but evolved into a production-ready application.
  • The development was broken down into steps with explanations of concepts.
  • The tutorial includes not just the final code but the approach to building such an application, such as setting up the tech stack.
  • The process includes UI development, database setup, and integration of various tools and libraries.
  • Production Readiness:
  • The application uses a serverless PostgreSQL database.
  • The application includes rate limiting to prevent abuse.
  • The application uses automated workflows for email notifications.

The sources provide a comprehensive overview of how to build a sophisticated, production-ready application using modern web development technologies and practices. The process is iterative, starting with UI components, then integrating with a database, and finally implementing advanced features like authentication, rate limiting, and automated workflows.

Full-Stack Library Management System Database Interactions

The sources detail extensive database interactions within the full-stack library management system, covering various aspects such as setup, schema design, querying, and data manipulation. Here’s a breakdown of the key database interactions:

  • Database Choice and Setup:
  • The system uses PostgreSQL as its primary database.
  • Neon is utilized to manage the PostgreSQL database in a serverless environment. Neon offers features like instant provisioning, autoscaling, database branching, and APIs.
  • The database connection string is configured using environment variables.
  • Object-Relational Mapping (ORM):
  • Drizzle ORM is used to interact with the database, chosen for its type safety and ease of use with TypeScript.
  • Drizzle simplifies database interactions and allows for more scalable database architecture.
  • Drizzle also provides a studio for exploring and manipulating data.
  • Schema Definition:
  • Database schemas are defined using Drizzle’s syntax in TypeScript, which is then translated into SQL.
  • The schema includes tables for users, books, and borrow records.
  • The users table includes fields for user authentication, personal information, and account status. It also includes enums for the user’s status and role.
  • The books table includes fields for book details, such as title, author, genre, rating, cover, description, and number of copies.
  • The borrow records table tracks which users borrowed which books, along with borrow and due dates.
  • Unique identifiers (uid) are used as primary keys.
  • The schemas use data types such as integer, text, varchar, uid, date, and timestamp.
  • Data Manipulation:
  • Drizzle’s methods like select, insert, update, and delete are used to perform database operations.
  • The application fetches data using queries that include conditions, limits, and ordering.
  • Data is inserted into tables using the insert method, which takes values to be added and returns the inserted record.
  • The update method modifies records based on specified conditions.
  • Database queries are type-safe, ensuring that data is correctly structured.
  • Data is often limited to specific numbers of records and filtered using the where clause.
  • Database Migrations:
  • Drizzle Kit is used to generate and apply database migrations.
  • Migrations are used to manage changes to the database schema over time.
  • Commands like drizzle kit generate and drizzle kit migrate are used to create SQL migration files and apply them to the database.
  • The migrations are stored in a dedicated folder.
  • Seeding Data:
  • A script is used to seed the database with initial data, such as dummy books.
  • The seeding process involves reading data from a JSON file and inserting it into the database using Drizzle.
  • The script handles uploading images to ImageKit and then inserting book information into the database using Drizzle.
  • The seeding process includes uploading the images and video of the books to image kit and using those URLs to populate the database.
  • Transaction Management:
  • The source doesn’t explicitly detail transaction management, but it does imply the use of transactions with Drizzle ORM for data integrity.
  • Specific Database Interactions:
  • User authentication involves querying the database for users based on email and password.
  • User data is updated when users log in or interact with the application.
  • Admin users are identified by querying the database to check their role.
  • Book borrowing involves checking book availability and then updating both the books and borrow records tables.

These database interactions are crucial to the library management system’s operation. The use of Drizzle ORM, coupled with Neon and PostgreSQL provides a robust and scalable approach to data management. The system also uses a secondary database (Redis through Upstash) for caching, rate limiting, and workflows. This shows how multiple databases can be used together in a single system to enhance performance and efficiency.

Library Management System Authentication

User authentication in the library management system is a critical component, designed to ensure secure access and manage user roles effectively. Here’s a detailed overview of how authentication is handled, based on the sources:

  • Authentication Method:
  • The system uses email and password for authentication.
  • The implementation is based on OAuth.js (next-auth), a free and open-source library for handling authentication in Next.js applications.
  • The system also implements JSON Web Tokens (JWT) for session management.
  • Credentials Provider:
  • A custom credentials provider is set up to manage the authentication logic.
  • The provider handles user sign-up and sign-in processes.
  • It validates credentials by checking if an email and password are provided.
  • It fetches user data from the database, based on the provided email.
  • Password Handling:
  • User passwords are hashed before being stored in the database for security.
  • The bcryptjs library is used for password hashing and comparison.
  • Sign-up Process:
  • The sign-up process involves collecting user information, including full name, email, University ID, password, and a university ID card image.
  • The system performs full validation of the sign-up form.
  • New users are added to the database with a default status of “pending” and a role of “user”.
  • Upon successful sign-up, a welcome email is sent to the user using an automated workflow.
  • After creating a new user, the system also automatically signs the user in.
  • Sign-in Process:
  • The sign-in process involves validating the email and password against the stored user credentials.
  • The system uses the credentials provider to check for the validity of the password and retrieve user data.
  • If the credentials are valid, the user is signed in and a session is created.
  • Session Management:
  • The system uses JWT for session management, which is configured within the next-auth config file.
  • The JWT is populated with the user’s ID and name.
  • A session provider is used to manage user sessions across the application.
  • The session is populated with the currently logged-in user data, making it accessible to components.
  • User Roles:
  • Users can have different roles, such as “user” and “admin”, which determine their permissions.
  • The user’s role is stored in the database and checked when accessing certain parts of the application.
  • Admins have access to the admin dashboard and can manage users, books, and other aspects of the library system.
  • The system ensures that only admin users can access the admin dashboard.
  • Authentication Logic:
  • The authentication logic is implemented within the auth.ts file located in the root directory.
  • This file configures OAuth.js and specifies how to interact with the database.
  • Server Actions:
  • Server actions are used for secure server-side operations, such as signing up and signing in users.
  • These actions are executed on the server, ensuring that sensitive data and operations are protected.
  • Rate Limiting:
  • Rate limiting is implemented using Upstash Redis to protect against brute force attacks and DDOS.
  • The system limits the number of requests from a single IP address within a given time frame.
  • Users who exceed the rate limit are redirected to a “too fast” page.
  • Logout:
  • A logout function is implemented to terminate the user session.
  • The logout button is placed at the top right in the header.
  • Redirects:
  • The system includes redirects to ensure that users are properly directed to the sign-in page if they are not logged in.
  • Similarly, users who are logged in are redirected to the homepage from the sign-in page.
  • Admin users that try to access the admin interface are redirected to the public app, unless their role is set to “admin”.
  • User Activity Tracking:
  • The system tracks the last activity date of the user and stores it in the database.
  • This information is used to send emails to users that have been inactive for a period of time.
  • The system updates the user’s last activity date once per day to limit database mutations.

This comprehensive approach to user authentication ensures that the library management system is secure, user-friendly, and well-equipped to manage different user roles and interactions effectively.

Workflow Automation with Upstash Qstash and Resend

Workflow automation is a key aspect of the library management system, designed to streamline various processes and enhance user engagement. The system uses Upstash Qstash workflows to manage these automated tasks. Here’s a breakdown of how workflow automation is implemented:

  • Workflow Management:
  • Upstash Qstash is used as a serverless platform for managing and automating workflows.
  • Qstash allows for the creation of durable, reliable, and performant serverless functions.
  • The workflows are designed to be resilient to failures and can pick up where they left off in case of temporary outages.
  • They support long-running executions, making them suitable for complex tasks such as data processing or sending email notifications.
  • Workflow Endpoints:
  • Workflow endpoints are defined as a set of steps, each containing a piece of business logic.
  • These endpoints are created within the Next.js API directory, typically under a /workflows route.
  • The routes contain the logic for triggering and managing workflow actions.
  • Workflow Client:
  • A workflow client is created to trigger the workflows.
  • This client uses the Upstash Qstash URL and token to connect to the Qstash service.
  • The client is used in the application’s server actions to start the defined workflows.
  • Onboarding Workflow:
  • The system implements a customer onboarding workflow as an example, which is triggered when a new user signs up.
  • The workflow includes steps such as:
  • Sending a welcome email to new users.
  • Waiting for a specified period of time (e.g., 3 days) before further actions.
  • Checking the user’s activity state periodically.
  • Sending different emails based on user activity status (active or non-active).
  • The onboarding workflow logic is defined within the /api/workflows/onboarding/route.ts file.
  • Email Notifications:
  • The workflows are integrated with Resend, an email API for developers, to send emails.
  • The emails are sent using the publishJson method provided by Qstash, which is integrated with Resend.
  • The workflow sends emails based on specific conditions, such as when a user signs up, has been inactive for 3 days, or is active.
  • Custom email content, including the subject and the message, is set using parameters passed to the sendEmail function.
  • The emails are sent from a custom domain that has been verified with Resend.
  • User Activity Checks:
  • The system checks for user activity by tracking the last activity date in the database.
  • The user’s activity state (active or non-active) is determined based on a custom function which checks if the time difference between the user’s last activity date and the current date is greater than a certain threshold.
  • If a user has not been active for a specified period (e.g., 3 days), an email notification is sent to prompt them to visit the website.
  • If the user has been active, they might receive a newsletter or a welcome back email.
  • The activity checks are done periodically, and appropriate actions are taken based on the state.
  • The user’s last activity date is updated only once per day to limit database mutations.
  • Workflow Triggering:
  • Workflows are triggered by calling the workflowClient.trigger method.
  • The trigger method includes the URL of the workflow endpoint, as well as any required parameters (e.g., email and full name of the user for the onboarding workflow).
  • The onboarding workflow is triggered immediately after a new user signs up through the auth.ts action file.
  • Customizable Workflows:
  • The workflow logic is highly customizable and can be tailored to specific application needs.
  • The email content, scheduling intervals, conditions, and user state checks can be modified as required.
  • Workflows can be used for many types of automations, including on-boarding, notifications, reminders, data processing, and more.
  • Code Implementation:
  • The core workflow logic is implemented within the lib/workflow.ts file, which contains the workflow client and the email sending logic.
  • The workflow endpoint logic is implemented in the /app/api/workflows/onboarding/route.ts file.
  • The lib/actions/auth.ts file contains the server action that triggers the workflow.

This workflow automation system allows for a more dynamic and engaging user experience by providing timely notifications and ensuring that users are prompted to return to the platform when necessary. The combination of Qstash workflows with Resend emails provides a flexible and reliable solution for automating various business processes within the library management system.

Production-Ready Library Management System

The library management system is designed with several features that contribute to its production readiness, ensuring it can handle real-world demands and maintain a high level of performance and security. Here’s a breakdown of the key aspects:

  • Scalable Architecture:
  • The system is built using a monorepo architecture, which allows for the management of two interconnected applications (the public-facing app and the admin dashboard) within a single repository.
  • This structure promotes code sharing, consistency, and easier management of the entire application.
  • The use of Next.js as the framework enables the creation of high-quality web applications with the power of React components, making the app scalable and performant.
  • Modern Tech Stack:
  • The system utilizes a modern tech stack including Next.js, TypeScript, Tailwind CSS, Shadcn/ui, PostgreSQL (with Neon), Drizzle ORM, Upstash Redis, ImageKit, and Resend.
  • These are all industry-standard, open-source, and production-ready technologies.
  • TypeScript is used to ensure a scalable and maintainable code base.
  • Tailwind CSS and Shadcn/ui are used for efficient and flexible styling of the application.
  • Database Management:
  • PostgreSQL, powered by Neon, is used as the primary database, which allows for a serverless setup, auto-scaling, and database branching.
  • Drizzle ORM is used to interact with the database, making database operations faster and simpler.
  • The system employs database migrations, which are generated based on the schema defined in the code, to manage database changes effectively.
  • Data seeding is implemented to populate the database with initial sets of data for testing and development purposes.
  • Caching and Rate Limiting:
  • Upstash Redis is used for efficient caching, session management, and rate limiting.
  • Rate limiting is implemented to prevent DDOS attacks and brute force attempts by limiting the number of requests from a specific IP address within a given time frame.
  • The system redirects users to a “too fast” page if the rate limit is exceeded.
  • Media Management:
  • ImageKit is used for real-time media processing APIs, asset management, and optimizing images and videos.
  • ImageKit provides dynamic transformations, storage, and streaming capabilities, which are perfect for delivering media assets to any device.
  • Automated Workflows:
  • Upstash Qstash workflows are used to manage automated tasks like sending emails, checking user activity, and managing book borrowing notifications.
  • Workflows are used to implement user onboarding flows, which involve sending welcome emails and checking for user inactivity.
  • The system uses Resend for sending emails, allowing for custom email templates built with React components.
  • Authentication and Authorization:
  • The system uses OAuth.js for secure authentication, which manages sign-up, sign-in, and user sessions.
  • JSON Web Tokens (JWT) are used for session management.
  • User roles are used to define permissions, ensuring that only admins can access the admin dashboard.
  • Bcryptjs is used for password hashing and comparison, providing a more secure way to store passwords in the database.
  • Error Handling:
  • The system implements comprehensive error handling using try and catch blocks, console logs, and descriptive toast notifications for both users and developers.
  • The system uses loaders and performance optimization to handle errors gracefully without blocking other parts of the application.
  • Deployment:
  • The application is deployed using Vercel, ensuring scalability and reliability.
  • The system utilizes environment variables for configuration management, which are set up in both local and production environments.
  • The system separates development and production environments to avoid conflicts.
  • UI and UX Design:
  • The user interfaces are designed to be modern, polished, and easy to navigate, using Tailwind CSS and Shadcn/ui.
  • The system uses toast notifications to provide feedback to the user during different actions, including sign-up, sign-in, and form submissions.
  • The design is responsive and user-friendly, providing a consistent user experience across different devices.
  • The application uses loading states to show progress for actions like image uploads and book borrowing.
  • Code Quality and Practices:The codebase is well-structured, scalable, and maintained using Prettier and ESLint.
  • The system uses clear coding practices with meaningful variable names and comments.
  • The system promotes code reusability and creates reusable components, such as the file upload component, which can be used for different input types.

These elements collectively ensure the library management system is not just a functional application, but a production-ready solution that adheres to industry standards and best practices. The system is designed to be scalable, secure, and easily maintainable, providing a solid foundation for future growth and feature additions.

Build and Deploy a Fullstack App with Admin Dashboard | Next.js, PostgreSQL, Redis, Auth.js

By Amjad Izhar
Contact: amjad.izhar@gmail.com
https://amjadizhar.blog


Discover more from Amjad Izhar Blog

Subscribe to get the latest posts sent to your email.

Comments

Leave a comment