Home Projects Jportal Architecture Overview Data Layer And Api Integration

Data Layer & API Integration

Purpose and Scope

This document describes the data access layer in JPortal, which abstracts backend communication through a portal interface. The system supports two operational modes: real mode (connecting to the actual JIIT Web Portal via the jsjiit library) and demo mode (using local mock data). This abstraction allows seamless switching between modes without changing feature component code.

For information about how authentication state is managed at the application level, see Application Structure & Authentication. For details on how feature components manage data retrieved from the portal, see State Management Strategy.


Portal Abstraction Layer

JPortal implements a strategy pattern where all feature components interact with a uniform portal interface through the w prop. This prop contains either a WebPortal instance (real mode) or a MockWebPortal instance (demo mode), both implementing the same API surface.

Portal Instantiation and Mode Switching

Architecture Diagram

Sources: src/App.jsx27-29 src/App.jsx243-250 src/App.jsx359-360

The portal instances are created at the top level of App.jsx:

The activePortal is determined by the isDemoMode state at src/App.jsx250 and passed to AuthenticatedApp as the w prop at src/App.jsx360

Sources: src/App.jsx1-376


Portal Interface Contract

Both portal implementations expose identical async methods. Feature components consume these methods through the w prop without knowledge of the underlying implementation.

Core API Methods

Method Parameters Returns Used By
student_login() username, password Promise<boolean> Login
get_attendance_meta() - {semesters, latest_header, latest_semester} Attendance
get_attendance() header, semester {studentattendancelist} Attendance
get_subject_daily_attendance() semester, subjectid, individualsubjectcode, subjectcomponentids {studentAttdsummarylist} Attendance
get_sgpa_cgpa() - {gradecard} Grades
get_semesters_for_grade_card() - Array<semester> Grades
get_grade_card() semester {gradecard} Grades
get_semesters_for_marks() - Array<semester> Grades
download_marks() semester {courses} Grades
get_registered_semesters() - Array<semester> Subjects
get_registered_subjects_and_faculties() semester {subjects, registered_subject_faculty} Subjects
get_semesters_for_exam_events() - Array<semester> Exams
get_exam_events() semester Array<event> Exams
get_exam_schedule() event {subjectinfo} Exams
get_personal_info() - {personal, academic, contact, family, address} Profile

Sources: src/components/MockWebPortal.js1-114


Real Mode: WebPortal (jsjiit Library)

Integration and Session Management

Architecture Diagram

Sources: src/App.jsx18 src/components/Login.jsx51

The WebPortal class is imported from the jsjiit library via CDN:

import { WebPortal, LoginError } from 
  "https://cdn.jsdelivr.net/npm/jsjiit@0.0.20/dist/jsjiit.esm.js";

Authentication Flow:

  1. User submits credentials via Login component at src/components/Login.jsx90-95
  2. w.student_login(enrollmentNumber, password) is called at src/components/Login.jsx51
  3. If successful, credentials are stored in localStorage at src/components/Login.jsx54-55
  4. The WebPortal instance maintains a session object with authentication state

Auto-login on App Load: The app attempts auto-login using stored credentials at src/App.jsx252-264 If successful, realPortal.session is populated and isAuthenticated is set to true.

Error Handling: The LoginError exception is caught and handled with specific error messages:

Sources: src/App.jsx252-288 src/components/Login.jsx46-87


Demo Mode: MockWebPortal

Implementation Architecture

Architecture Diagram

Sources: src/components/MockWebPortal.js1-114 src/assets/fakedata.json1-3199

Key Implementation Details

Mock Session Object: The constructor creates a fake session at src/components/MockWebPortal.js4-6:

this.session = { get_headers: async () => ({}) };

Semester Ordering Logic: The get_attendance_meta() method includes intelligent semester ordering based on the current month at src/components/MockWebPortal.js13-45:

  • January-July: Even semester (EVESEM) appears first
  • August-December: Odd semester (ODDSEM) appears first

This provides a realistic demo experience where the "current" semester is pre-selected.

Lookup Strategy: Most methods perform key-based lookups into the fakeData object:

// Example from get_attendance() at line 48-50
async get_attendance(header, semester) {
  const semKey = semester.registration_code || semester;
  return fakeData.attendance.attendanceData[semKey] || { studentattendancelist: [] };
}

Sources: src/components/MockWebPortal.js3-114


Authentication Flow Comparison

Architecture Diagram

Sources: src/components/Login.jsx40-43 src/components/Login.jsx49-63 src/App.jsx290-298

Auto-Login on Startup

When the app loads, it attempts auto-login using stored credentials (real mode only):

  1. Check localStorage for username and password at src/App.jsx253-254
  2. If found, call realPortal.student_login() at src/App.jsx259
  3. On success, set isAuthenticated = true and isDemoMode = false at src/App.jsx261-262
  4. On failure, clear stored credentials at src/App.jsx279-280

Demo mode has no auto-login; users must explicitly click "Try Demo".

Sources: src/App.jsx252-288


Data Flow in Feature Components

Consumption Pattern

All feature components receive the w prop and call portal methods to fetch data. The pattern is consistent across features:

Architecture Diagram

Sources: src/App.jsx110-214

Example: Attendance Component

The Attendance component demonstrates the typical data fetching pattern:

Props received at src/App.jsx113-141:

  • w - Portal instance
  • State variables and setters for caching data
  • Loading and error state management

Data fetching flow (pseudocode from typical feature component pattern):

useEffect(() => {
  const fetchData = async () => {
    setLoading(true);
    try {
      const meta = await w.get_attendance_meta();
      setSemestersData(meta.semesters);
      setSelectedSem(meta.latest_semester());

      const data = await w.get_attendance(meta.latest_header(), meta.latest_semester());
      setAttendanceData({ [meta.latest_semester().registration_code]: data });
    } catch (error) {
      setError(error.message);
    } finally {
      setLoading(false);
    }
  };
  fetchData();
}, [w]);

The component never checks whether w is real or mock - it simply calls the methods.

Sources: src/App.jsx110-142

Example: Grades Component

The Grades component shows multiple portal calls for different data types:

Props received at src/App.jsx146-181:

  • w - Portal instance
  • Separate state slices for: gradesData, gradeCards, marksData
  • Multiple semester selectors for different tabs

Multiple API calls pattern:

  • w.get_sgpa_cgpa() for CGPA trends
  • w.get_semesters_for_grade_card() to populate semester selector
  • w.get_grade_card(semester) when user selects a semester
  • w.download_marks(semester) for PDF parsing

Each call stores results in its own state slice, preventing conflicts between different data types.

Sources: src/App.jsx144-182


Mock Data Structure

The fakedata.json file contains comprehensive mock data organized into five domains corresponding to the five main features.

Data Organization

Architecture Diagram

Sources: src/assets/fakedata.json1-3199

Attendance Domain Structure

Semesters metadata at src/assets/fakedata.json3-18:

  • Array of semester objects with registration_id and registration_code
  • latest_header identifier for API compatibility
  • latest_semester pointer

Attendance data at src/assets/fakedata.json20-284:

  • Keyed by semester code (e.g., "2025EVESEM")
  • Contains studentattendancelist array
  • Each subject has: subjectcode, subjectdesc, L/T/P totals and percentages

Subject-level attendance at src/assets/fakedata.json286-2090:

  • Keyed by individualsubjectcode (e.g., "15B11EC611")
  • Array of attendance records with: datetime, classtype, present, attendanceby
  • Detailed daily attendance data for the Attendance tracker feature

Sources: src/assets/fakedata.json2-2090

Grades Domain Structure

SGPA/CGPA data at src/assets/fakedata.json2092-2145:

  • gradecard array with semester-wise GPA records
  • Used for the Overview tab trend chart

Grade cards at src/assets/fakedata.json2153-2576:

  • Keyed by semester code
  • Contains gradecard array with course-wise grades
  • Subject-level SGPA information

Marks data at src/assets/fakedata.json2625-2965:

  • Keyed by semester code
  • Contains courses array mimicking PDF export structure
  • Component-wise marks breakdown for each course

Sources: src/assets/fakedata.json2091-2965

Subjects, Exams, and Profile Domains

Subjects at src/assets/fakedata.json2967-3086:

  • semestersData with available semesters
  • subjectData keyed by semester with course info, credits, faculty details

Exams at src/assets/fakedata.json3088-3173:

  • examSemesters array
  • examEvents keyed by semester (e.g., Mid-term, End-term)
  • examSchedule keyed by event ID with exam timing and venue details

Profile at src/assets/fakedata.json3175-3198:

  • Flat structure with five sections: personal, academic, contact, family, address
  • Comprehensive student information

Sources: src/assets/fakedata.json2967-3199


Data Caching Strategy

Component-Level Caching

Feature components maintain their own data caches using React state, lifted to AuthenticatedApp. This prevents redundant API calls:

Example: Attendance caching pattern

// In AuthenticatedApp at <FileRef file-url="https://github.com/codeblech/jportal/blob/4df0fde4/src/App.jsx#L34-L35" min=34 max=35 file-path="src/App.jsx">Hii</FileRef>
const [attendanceData, setAttendanceData] = useState({});
const [attendanceSemestersData, setAttendanceSemestersData] = useState(null);

The attendanceData object is keyed by semester code:

{
  "2025EVESEM": { studentattendancelist: [...] },
  "2025ODDSEM": { studentattendancelist: [...] }
}

When switching semesters, components check if data exists before fetching:

if (!attendanceData[selectedSem.registration_code]) {
  const data = await w.get_attendance(header, selectedSem);
  setAttendanceData({ ...attendanceData, [selectedSem.registration_code]: data });
}

Sources: src/App.jsx32-89

LocalStorage Persistence

Only authentication credentials and user preferences are persisted:

Stored items:

API response data is not persisted to localStorage; it's fetched fresh on each session.

Sources: src/App.jsx52-61 src/components/Login.jsx54-55


Error Handling and Network Resilience

Error Types

The application handles three categories of errors from the real portal:

  1. Server Unavailability: JIIT portal is down

    • Detected via LoginError message check at src/App.jsx266-270
    • User message: "JIIT Web Portal server is temporarily unavailable"
  2. Network Errors: User has no internet connection

    • Detected via "Failed to fetch" message at src/App.jsx271-274
    • User message: "Please check your internet connection"
  3. Authentication Errors: Invalid credentials

Fallback to Demo Mode

When the real portal is unavailable, users can switch to demo mode via the "Try Demo" button on the login screen at src/components/Login.jsx159-167 This provides a functional demo experience without backend connectivity.

Sources: src/App.jsx265-281 src/components/Login.jsx64-82 src/components/Login.jsx159-167


Summary

The JPortal data layer provides a clean abstraction that:

  1. Decouples feature components from backend implementation details via the w prop strategy pattern
  2. Enables seamless switching between real and demo modes without code changes
  3. Provides comprehensive mock data in fakedata.json covering all five feature domains
  4. Implements component-level caching to minimize redundant API calls
  5. Handles network errors gracefully with clear user feedback

This architecture allows offline development, easy testing, and a fully functional demo mode while maintaining production compatibility with the actual JIIT Web Portal.

Sources: src/App.jsx1-376 src/components/MockWebPortal.js1-114 src/assets/fakedata.json1-3199 src/components/Login.jsx1-174