Skip to main content

RISTEK Link

📖 Table of Contents

1. Introduction

RISTEK Link is a modern URL shortener and link management platform built for RISTEK Universitas Indonesia. This documentation provides a comprehensive technical overview of both frontend and backend implementations, including architecture, core technologies, and key features.

2. Core Technologies

Backend Technologies

  • Framework: Express.js
  • Language: TypeScript
  • Database: FireStore
  • Authentication: Standard Auth and Google OAuth
  • Logging: Winston
  • Mailer Service: Sendinblue
  • Analytics: Mixpanel
  • Error Tracking: Sentry
  • Risk Mitigation: Google Web Risk API

Frontend Technologies

  • Framework: Next.js 12 (using App Router)
  • UI Libraries:
    • Chakra UI
    • TailwindCSS
    • Material UI
    • Framer Motion
  • Authentication: Google OAuth
  • Analytics:
    • Mixpanel
    • Chart.js
  • Monitoring: Sentry
  • Other Libraries:
    • Axios for API requests
    • AWS SDK for cloud services
    • QR Code generation
    • JWT for token management

3. Project Setup

(Details about local development setup, build commands, etc., would typically go here. Assuming standard Next.js setup.)

  1. Clone the repository.
  2. Install dependencies:
npm install
# or
yarn install
  1. Set up environment variables: Create a .env.local file based on .env.example (if available) or the Environment Variables section.
  2. Run the development server:
npm run dev
# or
yarn dev
  1. Build for production:
npm run build
# or
yarn build

4. 🔐 Environment Variables

The application relies on several environment variables for its configuration. These should be defined in a .env.local file in the project root.

a. Backend Environment Variables

Variable NameDescriptionExpected FormatExample
PORTPort number on which the backend server runs.Integer5000
JWT_SECRETSecret key used for signing and verifying JWTs.Arbitrary string<INSERT_JWT_SECRET_HERE>
NODE_ENVNode environment (development or production).development | productiondevelopment
SENDINBLUE_API_KEYAPI key for Sendinblue email service.String<INSERT_SENDINBLUE_API_KEY_HERE>
CLIENT_HOSTURL for the client-side reset password page with token parameter.URL stringhttp://localhost:3000/login/reset?token=

b. Frontend Environment Variables

Variable NameDescriptionExpected FormatExample
NEXT_PUBLIC_GOOGLE_CLIENT_IDGoogle OAuth client IDStringyour-client-id.apps.googleusercontent.com
NEXT_PUBLIC_API_URLBase URL for API endpointsURL stringhttps://api.example.com
NEXT_PUBLIC_MIXPANEL_TOKENMixpanel analytics tokenStringyour-mixpanel-token
NEXT_PUBLIC_SENTRY_DSNSentry error tracking DSNURL stringhttps://your-sentry-dsn

5. 📁 Folder Structure

a. Backend Folder Structure

.
├── firebase.dev.json # Firebase configuration for development
├── firebase.json # Firebase configuration
├── package.json # Project metadata and dependencies
├── package-lock.json
├── src
│ ├── config.ts # Main configuration, index, and routes configuration
│ ├── controllers
│ │ ├── analyticsController.ts # Controller for analytics
│ │ ├── authController.ts # Controller for login, register, forgot password, and reset password
│ │ ├── domainController.ts # Controller for domain management
│ │ └── shortenController.ts # Controller for URL shortening, including malicious URL detection
│ ├── database
│ │ ├── blacklistedEmail.ts # Contains blacklisted email addresses
│ │ └── firestore.ts # Firestore initializer
│ ├── error
│ │ ├── error.ts # Common response error handler
│ │ └── serviceError.ts # Common service error exceptions
│ ├── index.ts
│ ├── log
│ │ └── log.ts # Logger configuration using Winston
│ ├── middlewares
│ │ ├── authorization.ts # Middleware for authorization
│ │ └── superuserAuthorization.ts # Middleware for superuser (admin) authorization
│ ├── routers
│ │ ├── analyticsRouter.ts # Router for analytics
│ │ ├── authRouter.ts # Router for authentication
│ │ ├── domainRouter.ts # Router for domain management
│ │ └── shortenRouter.ts # Router for URL shortening
│ ├── types
│ │ ├── analytics.ts # Types for analytics
│ │ ├── auth.ts # Types for authentication
│ │ ├── domain.ts # Types for domain management
│ │ └── shorten.ts # Types for URL shortening
│ └── utils
│ ├── mailer.ts # Mailer service for sending emails
│ ├── s3.ts # S3 service for storing bulk shortened URLs in xlsx format
│ ├── validator.ts # Validator for request body using express validator
│ ├── webrisk.ts # WebRisk API service for detecting malicious URLs
│ └── wrapper.ts # Wrapper service for common response
├── swagger.json # Swagger documentation for API
├── tsconfig.json # TypeScript configuration
└── vercel.json # Vercel configuration for deployment

b. Frontend Folder Structure

Detailed Frontend Structure:

.
├── components
│ ├── common
│ │ ├── Backdrop/
│ │ ├── Banner/
│ │ ├── Button/
│ │ ├── FeatureDrawer/
│ │ ├── Icon/
│ │ ├── Input/
│ │ └── URLDrawer/
│ ├── layout
│ │ ├── Footer/
│ │ ├── Layout.js
│ │ └── Navbar/
│ ├── pages
│ │ ├── Analytic/
│ │ ├── AuthPage/
│ │ ├── BulkShortener/
│ │ ├── GenerateQR/
│ │ ├── Landing/
│ │ ├── TermsOfService/
│ │ └── URLShotener/
│ └── utils
│ ├── downloadFromS3.js
│ └── useCustomToast.js
├── config
│ ├── apiTarget.js
│ └── awsConfig.js
├── context
│ ├── AuthContext
│ │ └── AuthContext.js
│ ├── BackdropContext
│ │ └── BackdropContext.js
│ ├── DrawerContext
│ │ └── DrawerContext.js
│ └── StateManagementContext
│ └── StateManagementContext.js
├── hooks
│ ├── useMixpanelClient.js
│ ├── useMixpanelServer.js
│ └── useWindowSize.js
├── next.config.js
├── package.json
├── package-lock.json
├── pages
│ ├── 404.js
│ ├── api
│ │ ├── analytic.js
│ │ ├── auth.js
│ │ ├── bulkShortener.js
│ │ ├── generateQR.js
│ │ ├── google.js
│ │ ├── logout.js
│ │ ├── register.js
│ │ ├── resetPassword.js
│ │ ├── shorten.js
│ │ ├── [...shortLink].js
│ │ └── urls.js
│ ├── _app.js
│ ├── bulk-shortener
│ │ └── index.js
│ ├── _error.js
│ ├── index.js
│ ├── login
│ │ ├── forgot.js
│ │ ├── index.js
│ │ └── reset.js
│ ├── maintenance.js
│ ├── register
│ │ └── index.js
│ └── terms-of-service.js
├── postcss.config.js
├── public
│ ├── favicon.ico
│ ├── images
│ ├── logo.ico
│ └── vercel.svg
├── README.md
├── sentry.client.config.js
├── sentry.properties
├── sentry.server.config.js
├── styles
│ ├── globals.css
│ └── theme.js
└── tailwind.config.js

7. 🌐 API Endpoints

Base URL: /api/v1

Auth

MethodEndpointDescriptionAuth Required
POST/auth/registerRegister new userNo
POST/auth/loginLogin with email/passwordNo
POST/auth/googleLogin with GoogleNo
POST/auth/forgot-passwordRequest password resetNo
POST/auth/reset-passwordReset password with tokenNo

URL Shortening

MethodEndpointDescriptionAuth Required
POST/shortenCreate short URLNo
POST/shorten/bulkBulk shorten URLs from ExcelNo
GET/shortenList user's URLsYes
GET/shorten/bulkList bulk Excel filesYes
PUT/shortenEdit short URLYes
POST/shorten/redirectGet redirect infoNo
PATCH/shorten/generate-qrGenerate QR codeNo

Analytics

MethodEndpointDescriptionAuth Required
GET/analyticsGet URL analyticsYes

Domain Management

MethodEndpointDescriptionAuth Required
POST/domainCreate custom domainSuper User
POST/domain/findCheck user's domainYes
PATCH/domain/:idUpdate domainSuper User
DELETE/domain/:idDelete domainSuper User
PATCH/domain/:id/active-statusToggle domain statusSuper User
GET/domain/allList all domainsSuper User

Authentication

Add token to request header:

Authorization: Bearer <token>

Common Request/Response Examples

Short URL Creation

POST /shorten
{
"email": "user@example.com",
"url": "https://example.com",
"shorten": "custom-path",
"subdomain": "custom"
}

Error Response

{
"errors": [{
"message": "Error description",
"code": "ERROR_CODE"
}]
}

8. 📊 Diagrams

Database Schema

URL Shortening Flow

Authentication Flow

URL Redirection Flow

Analytics Flow

Domain Management Flow

Application Flow

Component Architecture

9. 🔧 Development Notes

  1. Code Style

    • Follow ESLint configuration
    • Use TypeScript for type safety
    • Follow component-based architecture
  2. Performance Considerations

    • Implement lazy loading for components
    • Optimize images and assets
    • Use proper caching strategies