Handover workspace

ERS, Todo, OfferReview, and Docu in one view

Imported from live server docs, code structure, and deployment notes.

Apr 3, 2026, 12:38 PM

OfferReview

W1 Implementation: Login

Implemented a complete login flow with email/password authentication, JWT token generation, role-based routing, and audit logging. Users can login and are redirected based on their role (HR/Manager/SMO → /dashboard, Admin → /admin/access-requests).

W1-LOGIN-IMPLEMENTATION.md

Updated Feb 19, 2026, 6:59 AM

Codex 5.3 Refactor Note: Canonical refactor plan: docs/CODEX-5.3-REFACTOR-PLAN.md. This document is retained for historical and implementation context during the refactor.

W1 Implementation: Login

A. Summary

Implemented a complete login flow with email/password authentication, JWT token generation, role-based routing, and audit logging. Users can login and are redirected based on their role (HR/Manager/SMO → /dashboard, Admin → /admin/access-requests).

B. Routes Implemented

  • GET /login – Login page with form
  • POST /api/auth/login – Authentication endpoint
  • GET /forgot-password – Stub page (coming soon)
  • GET /request-access – Stub page (coming soon)
  • GET /dashboard – User dashboard (stub)
  • GET /admin/access-requests – Admin requests page (stub)

C. Data Model Changes

Prisma Schema Updates

Added to prisma/schema.prisma:

  • enum Role – ADMIN, HR, MANAGER, SMO
  • enum UserStatus – ACTIVE, INACTIVE, PENDING_APPROVAL
  • enum AuditEventType – USER_LOGIN_SUCCESS, USER_LOGIN_FAILED (+ others for future wireframes)
  • model User – id, email, passwordHash, role, status, createdAt, updatedAt
  • model AuditLog – id, eventType, userId, details (JSON), createdAt

Migration Steps

cd /Users/rezafahmi/projectweb-nextjs

# Create .env.local with DATABASE_URL and JWT_SECRET
# Example:
# DATABASE_URL="postgresql://user:password@localhost:5432/offer_review"
# JWT_SECRET="your-secret-key"

# Initialize database
npx prisma migrate dev --name init

# Seed test data
npx prisma db seed

D. UI Components Created

Components

E. API Logic Created

Files

Endpoint Details

POST /api/auth/login

  • Request: { email: string, password: string }
  • Response (Success):
    {
      "success": true,
      "user": {
        "id": "...",
        "email": "...",
        "role": "ADMIN|HR|MANAGER|SMO"
      }
    }
    
    Sets auth_token httpOnly cookie (7 days expiry)
  • Response (Error):
    • 400: Missing email/password
    • 401: Invalid credentials or inactive user
    • 403: Account pending approval or inactive
    • 500: Server error

Flow

  1. Validate email/password format
  2. Query user by email
  3. Check user status (must be ACTIVE)
  4. Verify password hash
  5. Generate JWT token: { userId, email, role }
  6. Set httpOnly secure cookie
  7. Log audit event (USER_LOGIN_SUCCESS or USER_LOGIN_FAILED)
  8. Return user data

F. RBAC Checks

Login Endpoint

  • No authentication required
  • Validates user exists in DB
  • Validates user status = ACTIVE
  • Invalid status returns 403 with appropriate message

Post-Login Routing

  • HR/Manager/SMO roles → /dashboard
  • ADMIN role → /admin/access-requests

Audit Logging

  • Successful login: USER_LOGIN_SUCCESS (logged with email)
  • Failed login: USER_LOGIN_FAILED (logged with email + reason)
    • Reasons: "User not found", "Invalid password", "User status is PENDING_APPROVAL", etc.

G. Audit Events

USER_LOGIN_SUCCESS

{
  "eventType": "USER_LOGIN_SUCCESS",
  "userId": "...",
  "details": {
    "email": "user@example.com"
  }
}

USER_LOGIN_FAILED

{
  "eventType": "USER_LOGIN_FAILED",
  "userId": "... or unknown",
  "details": {
    "email": "user@example.com",
    "reason": "Invalid password|User not found|User status is PENDING_APPROVAL|..."
  }
}

H. Test Checklist

Setup

  1. Create .env.local with DATABASE_URL (PostgreSQL) and JWT_SECRET
  2. Run npx prisma migrate dev --name init
  3. Run npx prisma db seed (creates test users)
  4. Run npm run dev to start development server

Test Users

Manual Tests

  • Navigate to http://localhost:3000/login
  • Enter admin@example.com + admin123 → redirects to /admin/access-requests
  • Enter hr@example.com + hr123 → redirects to /dashboard
  • Enter invalid email → shows error "Invalid email or password"
  • Enter wrong password → shows error "Invalid email or password"
  • Enter non-existent email → shows error "Invalid email or password"
  • Leave email/password empty → shows error "Email and password are required"
  • Test loading state during login
  • Verify browser cookies: auth_token should be httpOnly cookie
  • Click "Forgot password?" → navigates to /forgot-password (stub page)
  • Click "Submit a registration request" → navigates to /request-access (stub page)
  • Check database: User table has all test users
  • Check database: AuditLog table logs USER_LOGIN_SUCCESS and USER_LOGIN_FAILED events

Database Verification

# Connect to Prisma Studio
npx prisma studio

# Or query directly
npx prisma db push  # (if needed)

Next Steps (W2)

  • Implement W2: Request Access form (allows public users to request account creation)
  • Add email verification or approval workflow