Skip to content

Latest commit

 

History

History
447 lines (338 loc) · 8.77 KB

File metadata and controls

447 lines (338 loc) · 8.77 KB

Attendance Marking App — API Reference

Base URL: http://localhost:3000/api/v1
Auth: Bearer JWT token in Authorization header
Format: All requests/responses in JSON


Response Format

All endpoints return a consistent envelope:

{
  "success": true,
  "data": { ... },
  "error": null,
  "message": "Optional message",
  "timestamp": "2026-04-10T10:00:00.000Z"
}

On error:

{
  "success": false,
  "data": null,
  "error": {
    "message": "Human-readable error",
    "statusCode": 400,
    "details": [ ... ]
  },
  "timestamp": "..."
}

Authentication

POST /auth/login

Login with email and password.

Request

{ "email": "faculty@nmiet.edu", "password": "password123" }

Response 200

{
  "success": true,
  "data": {
    "user": {
      "id": "uuid",
      "email": "faculty@nmiet.edu",
      "fullName": "Dr. Smith",
      "role": "faculty",
      "departmentId": "uuid"
    },
    "token": "eyJ...",
    "refreshToken": "eyJ...",
    "expiresIn": "7d",
    "tokenType": "Bearer"
  }
}

Errors: 400 (validation), 401 (wrong credentials)
Rate limit: 5 requests/minute per IP


POST /auth/refresh

Exchange a refresh token for a new access token.

Request

{ "refreshToken": "eyJ..." }

Response 200

{ "data": { "token": "eyJ...", "expiresIn": "7d", "tokenType": "Bearer" } }

Errors: 400 (missing token), 401 (expired/invalid token)


Health

GET /health

Basic health check (used by load balancers).

Response 200

{ "status": "up", "uptime": 12345, "timestamp": "..." }

GET /ready

Readiness check — verifies database connectivity.

Response 200 (connected) or 503 (disconnected)

{ "ready": true, "database": "connected", "timestamp": "..." }

Timetable (Phase 2)

GET /timetable/:subjectId

Get all active timetable slots for a subject.

Auth: Faculty (own subjects only), HoD, Admin
Response 200: Array of timetable slots

{
  "data": [
    {
      "id": "uuid",
      "subjectId": "uuid",
      "dayOfWeek": 1,
      "startTime": "09:00",
      "endTime": "10:00",
      "room": "A101",
      "building": "Main Block",
      "capacity": 60
    }
  ]
}

POST /timetable/:subjectId

Create a new timetable slot.

Auth: Faculty (own subjects), Admin
Request

{
  "dayOfWeek": 1,
  "startTime": "09:00",
  "endTime": "10:00",
  "room": "A101",
  "building": "Main Block",
  "capacity": 60
}

Validation: dayOfWeek 1–7, startTime/endTime in HH:mm format
Errors: 409 (slot already exists for same time)


PUT /timetable/:slotId

Update a timetable slot.

Auth: Faculty (own subjects), Admin
Request: Any subset of { dayOfWeek, startTime, endTime, room, building, capacity }


DELETE /timetable/:slotId

Soft-delete a timetable slot.

Auth: Faculty (own subjects), Admin
Response 204: No content


Tentative Lectures (Phase 2)

POST /tentative-lectures/generate

Generate tentative lecture slots from a subject's timetable over a date range.

Auth: Faculty (own subjects), Admin
Request

{
  "subjectId": "uuid",
  "fromDate": "2026-06-01",
  "toDate": "2026-10-31",
  "excludePublicHolidays": true,
  "estimatedStudentCount": 60
}

Response 200: Array of generated (not yet saved) slots
Note: Slots are not persisted until /confirm is called.


POST /tentative-lectures/confirm

Save generated tentative lectures to the database.

Auth: Faculty, Admin
Request

{ "lectureIds": ["uuid1", "uuid2"] }

GET /tentative-lectures/subject/:subjectId

List tentative lectures for a subject.

Auth: Faculty (own), HoD, Admin
Query: ?status=scheduled&fromDate=2026-06-01&toDate=2026-10-31


PUT /tentative-lectures/:lectureId

Update a tentative lecture (reschedule, add notes).

Auth: Faculty (own), Admin


PUT /tentative-lectures/:lectureId/mark

Mark a tentative lecture as held or cancelled.

Auth: Faculty (own), Admin
Request

{ "status": "held", "notes": "Completed Unit 3" }

Side effect: When status = "held", creates a lectures record and emits a WebSocket event.


Lectures (Phase 1)

GET /lectures/:lectureId

Get lecture details with enrolled students and their attendance status.

Auth: Faculty (own subjects), HoD, Admin
Response 200

{
  "data": {
    "id": "uuid",
    "lectureDate": "2026-07-15",
    "startTime": "09:00",
    "endTime": "10:00",
    "subjectName": "Data Structures",
    "facultyName": "Dr. Smith",
    "totalStudents": 58,
    "totalPresent": 0,
    "students": [
      { "id": "uuid", "rollNumber": "CS001", "fullName": "Alice", "status": null }
    ]
  }
}

Attendance (Phase 1)

GET /attendance/subject/:subjectId

Get attendance history for a subject.

Auth: Faculty (own), HoD, Admin
Query: ?fromDate=2026-06-01&toDate=2026-10-31


POST /attendance/bulk

Mark attendance for all students in a lecture (idempotent).

Auth: Faculty (own subjects)
Request

{
  "lectureId": "uuid",
  "marks": [
    { "studentId": "uuid", "status": "present" },
    { "studentId": "uuid", "status": "absent" }
  ]
}

Response 200: Summary { lectureId, totalPresent, totalAbsent, savedCount }
Idempotent: Safe to call multiple times — re-submitting updates existing records.
Atomic: All marks saved in one transaction; partial saves never happen.


PUT /attendance/:attendanceId

Update a single attendance record (correction).

Auth: Faculty (own lecture), Admin
Request

{ "status": "present", "notes": "Student arrived late" }

Analytics (Phase 3)

GET /analytics/subject/:subjectId/summary

Summary statistics for a subject.

Auth: Faculty (own), HoD, Admin
Response 200

{
  "data": {
    "subjectId": "uuid",
    "totalLectures": 30,
    "avgAttendance": 82.5,
    "defaulterCount": 4,
    "topStudents": [ ... ],
    "defaulters": [ ... ]
  }
}

GET /analytics/subject/:subjectId/trends

30-day attendance trend + linear regression forecast.

Auth: Faculty (own), HoD, Admin
Query: ?days=30


GET /analytics/department/:departmentId/overview

Real-time department dashboard for HoD.

Auth: HoD (own department), Admin
WebSocket: Updates pushed when attendance is marked.


GET /analytics/department/:departmentId/at-risk

Students below attendance threshold across any subject.

Auth: HoD (own dept), Admin
Query: ?threshold=75


GET /analytics/institution/summary

Institution-wide attendance statistics.

Auth: Admin only


GET /analytics/subject/:subjectId/export

Export attendance data as CSV/PDF (async — returns S3 signed URL).

Auth: Faculty (own), HoD, Admin
Query: ?format=csv or ?format=pdf
Response: { "downloadUrl": "https://...", "expiresAt": "..." }


GET /analytics/department/:departmentId/export

Export full department report.

Auth: HoD (own), Admin


Admin (Phase 4)

GET /admin/audit-log

Query the immutable audit trail.

Auth: Admin only
Query: ?userId=uuid&action=attendance.mark&from=2026-01-01&to=2026-12-31&page=1&limit=50

Response

{
  "data": {
    "items": [
      {
        "id": "uuid",
        "userId": "uuid",
        "action": "attendance.mark",
        "entityType": "lecture",
        "entityId": "uuid",
        "ipAddress": "192.168.1.1",
        "createdAt": "..."
      }
    ],
    "pagination": { "total": 1250, "page": 1, "limit": 50, "totalPages": 25 }
  }
}

Compliance: Audit log is append-only. No records can be updated or deleted.


POST /admin/notifications/email-defaulters

Send email notifications to students below attendance threshold.

Auth: Admin, HoD
Request

{ "departmentId": "uuid", "threshold": 75, "message": "Custom message..." }

Error Codes

Status Meaning
200 Success
201 Created
204 No Content
400 Validation error (check error.details)
401 Authentication required or token expired
403 Insufficient permissions (RBAC)
404 Resource not found
409 Conflict (duplicate)
429 Rate limit exceeded
500 Server error
501 Not implemented (Phase 0 stub)
503 Service unavailable (DB disconnected)

RBAC Matrix

Endpoint Faculty HoD Admin
POST /auth/login
GET /timetable/:subjectId Own only Own dept
POST /attendance/bulk Own lectures
GET /analytics/department Own dept
GET /analytics/institution
GET /admin/audit-log