{"_id":"@campusiq/sdk","_rev":"2-ac8e3012285b41c46ab010d9082db2f7","name":"@campusiq/sdk","dist-tags":{"latest":"1.0.5"},"versions":{"1.0.3":{"name":"@campusiq/sdk","version":"1.0.3","keywords":["campusiq","school-management","education","api","sdk","student-information-system","sis","typescript","javascript"],"author":{"name":"CampusIQ Team","email":"dev@campusiq.edu"},"license":"MIT","_id":"@campusiq/sdk@1.0.3","maintainers":[{"name":"godwinadu","email":"gyamfiadu01@gmail.com"}],"homepage":"https://docs.campusiq.edu","bugs":{"url":"https://github.com/GodwinAdu/campus-iq-sdk.git/issues"},"dist":{"shasum":"dacc77b7699d38c73d9c613efba8ba18e32b966f","tarball":"https://registry.npmjs.org/@campusiq/sdk/-/sdk-1.0.3.tgz","fileCount":48,"integrity":"sha512-MQdysHckheVkrypRF3RJCV4lLEVmtpcq5m84w/VXla/+BgjV+TpHHngjL6hNniFLvMjdXjo9nq+b0DZazQYCag==","signatures":[{"sig":"MEUCIQCSmoGquCn10hZJhzqS1URirAI7g06db1HJCKsG6X3p+AIgUcS/drCV+ma0mE7gGOFfL5bJ/Q59Gdc5nekvE724mvo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":303701},"main":"src/index.ts","type":"module","types":"dist/index.d.ts","module":"dist/index.esm.js","engines":{"node":">=16.0.0"},"scripts":{"dev":"rollup -c -w","docs":"typedoc src/index.ts","lint":"eslint src --ext .ts,.js","test":"jest --passWithNoTests","build":"rollup -c","release":"semantic-release","lint:fix":"eslint src --ext .ts,.js --fix","typecheck":"tsc --noEmit","test:watch":"jest --watch","test:coverage":"jest --coverage","prepublishOnly":"npm run build && npm test","test:integration":"jest --config jest.integration.config.js"},"_npmUser":{"name":"godwinadu","email":"gyamfiadu01@gmail.com"},"repository":{"url":"git+https://github.com/GodwinAdu/campus-iq-sdk.git","type":"git"},"_npmVersion":"11.3.0","description":"Official JavaScript/TypeScript SDK for CampusIQ - A comprehensive school management system API","directories":{},"_nodeVersion":"24.0.1","dependencies":{"axios":"^1.6.0","tslib":"^2.8.1","crypto-js":"^4.2.0","rollup-plugin-dts":"^6.2.1","@rollup/plugin-json":"^6.1.0","rollup-plugin-terser":"^7.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","rollup":"^4.0.0","ts-jest":"^29.1.0","typedoc":"^0.25.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@types/crypto-js":"^4.2.0","semantic-release":"^22.0.0","@rollup/plugin-commonjs":"^25.0.0","@rollup/plugin-typescript":"^11.1.6","@typescript-eslint/parser":"^6.0.0","@rollup/plugin-node-resolve":"^15.3.1","@typescript-eslint/eslint-plugin":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk_1.0.3_1754731923294_0.6464508627267964","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@campusiq/sdk","version":"1.0.5","description":"Official JavaScript/TypeScript SDK for CampusIQ - A comprehensive school management system API","main":"dist/index.cjs.js","module":"dist/index.esm.js","types":"dist/index.d.ts","type":"module","scripts":{"build":"tsc && rollup -c","dev":"rollup -c -w","test":"jest --passWithNoTests","test:watch":"jest --watch","test:coverage":"jest --coverage","test:integration":"jest --config jest.integration.config.js","lint":"eslint src --ext .ts,.js","lint:fix":"eslint src --ext .ts,.js --fix","typecheck":"tsc --noEmit","docs":"typedoc src/index.ts","prepublishOnly":"npm run build && npm test","release":"semantic-release"},"keywords":["campusiq","school-management","education","api","sdk","student-information-system","sis","typescript","javascript"],"author":{"name":"CampusIQ Team","email":"dev@campusiq.edu"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/GodwinAdu/campus-iq-sdk.git"},"bugs":{"url":"https://github.com/GodwinAdu/campus-iq-sdk.git/issues"},"homepage":"https://docs.campusiq.edu","dependencies":{"@rollup/plugin-json":"^6.1.0","axios":"^1.6.0","crypto-js":"^4.2.0","rollup-plugin-dts":"^6.2.1","rollup-plugin-terser":"^7.0.2","tslib":"^2.8.1"},"devDependencies":{"@rollup/plugin-commonjs":"^25.0.0","@rollup/plugin-node-resolve":"^15.3.1","@rollup/plugin-typescript":"^11.1.6","@types/crypto-js":"^4.2.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/eslint-plugin":"^6.0.0","@typescript-eslint/parser":"^6.0.0","eslint":"^8.0.0","jest":"^29.5.0","rollup":"^4.0.0","semantic-release":"^22.0.0","ts-jest":"^29.1.0","typedoc":"^0.25.0","typescript":"^5.0.0"},"engines":{"node":">=16.0.0"},"publishConfig":{"access":"public"},"_id":"@campusiq/sdk@1.0.5","_nodeVersion":"24.0.1","_npmVersion":"11.3.0","dist":{"integrity":"sha512-0Tgibo61wY+6fSE11BJjauo2MBJYejw/4yh0EgkmpkrYkhU+fT7tc9BdIb3dbrDx1EmTyEGr8w3/mlvmGc8Y3w==","shasum":"c442e404b3b9c366b9962d55f0987364a135d8e8","tarball":"https://registry.npmjs.org/@campusiq/sdk/-/sdk-1.0.5.tgz","fileCount":58,"unpackedSize":246361,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDzIw+HW8u73Eg+bYwHEUIC3URQumBrs10c1nBAhKpVNAiEA167mqmbVZzDkC93msiKNu+5xi0ebjpYw9d3vbBGzwk4="}]},"_npmUser":{"name":"godwinadu","email":"gyamfiadu01@gmail.com"},"directories":{},"maintainers":[{"name":"godwinadu","email":"gyamfiadu01@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk_1.0.5_1754745640565_0.4753603216431348"},"_hasShrinkwrap":false}},"time":{"created":"2025-08-09T09:32:03.169Z","modified":"2025-08-09T13:20:41.023Z","1.0.3":"2025-08-09T09:32:03.485Z","1.0.5":"2025-08-09T13:20:40.815Z"},"bugs":{"url":"https://github.com/GodwinAdu/campus-iq-sdk.git/issues"},"author":{"name":"CampusIQ Team","email":"dev@campusiq.edu"},"license":"MIT","homepage":"https://docs.campusiq.edu","keywords":["campusiq","school-management","education","api","sdk","student-information-system","sis","typescript","javascript"],"repository":{"type":"git","url":"git+https://github.com/GodwinAdu/campus-iq-sdk.git"},"description":"Official JavaScript/TypeScript SDK for CampusIQ - A comprehensive school management system API","maintainers":[{"name":"godwinadu","email":"gyamfiadu01@gmail.com"}],"readme":"# CampusIQ SDK\n\n[![npm version](https://badge.fury.io/js/%40campusiq%2Fsdk.svg)](https://badge.fury.io/js/%40campusiq%2Fsdk)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/)\n\nThe official JavaScript/TypeScript SDK for CampusIQ - A comprehensive school management system API.\n\n## 🚀 Quick Start\n\n### Installation\n\n\\`\\`\\`bash\nnpm install @campusiq/sdk\n# or\nyarn add @campusiq/sdk\n# or\npnpm add @campusiq/sdk\n\\`\\`\\`\n\n### Basic Usage\n\n\\`\\`\\`javascript\nimport { CampusIQ } from '@campusiq/sdk';\n\nconst client = new CampusIQClient({\n  apiKey: 'your-api-key',\n  schoolId: 'your-school-id',\n  environment: 'production' // or 'sandbox'\n});\n\n// Get all students\nconst students = await client.students.list();\nconsole.log(students);\n\\`\\`\\`\n\n## 📚 Table of Contents\n\n- [Authentication](#authentication)\n- [Configuration](#configuration)\n- [API Resources](#api-resources)\n  - [Students](#students)\n  - [Teachers](#teachers)\n  - [Courses](#courses)\n  - [Enrollments](#enrollments)\n  - [Grades](#grades)\n  - [Attendance](#attendance)\n- [Error Handling](#error-handling)\n- [Pagination](#pagination)\n- [Filtering & Search](#filtering--search)\n- [Webhooks](#webhooks)\n- [TypeScript Support](#typescript-support)\n- [Examples](#examples)\n- [Contributing](#contributing)\n\n## 🔐 Authentication\n\nTo use the CampusIQ SDK, you need:\n\n1. **API Key**: Get your API key from the CampusIQ dashboard\n2. **School ID**: Your unique school identifier\n\n\\`\\`\\`javascript\nconst client = new CampusIQClient({\n  apiKey: 'ciq_a1b2c3d4_e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6',\n  schoolId: '64f8a1b2c3d4e5f6a7b8c9d0'\n});\n\\`\\`\\`\n\n### Getting Your Credentials\n\n1. Log in to your [CampusIQ Dashboard](https://dashboard.campusiq.edu)\n2. Navigate to **Settings** → **API Keys**\n3. Click **Create New API Key**\n4. Copy your API key and School ID\n\n## ⚙️ Configuration\n\n### Basic Configuration\n\n\\`\\`\\`javascript\nconst client = new CampusIQClient({\n  apiKey: 'your-api-key',\n  schoolId: 'your-school-id',\n  environment: 'production', // 'production' or 'sandbox'\n  timeout: 30000, // Request timeout in milliseconds\n  retries: 3, // Number of retry attempts\n  baseURL: 'https://api.campusiq.edu' // Custom base URL (optional)\n});\n\\`\\`\\`\n\n### Environment Variables\n\nYou can also use environment variables:\n\n\\`\\`\\`bash\nCAMPUSIQ_API_KEY=your-api-key\nCAMPUSIQ_SCHOOL_ID=your-school-id\nCAMPUSIQ_ENVIRONMENT=production\n\\`\\`\\`\n\n\\`\\`\\`javascript\nconst client = new CampusIQClient({\n  apiKey: process.env.CAMPUSIQ_API_KEY,\n  schoolId: process.env.CAMPUSIQ_SCHOOL_ID,\n  environment: process.env.CAMPUSIQ_ENVIRONMENT\n});\n\\`\\`\\`\n\n## 📖 API Resources\n\n### Students\n\n#### List Students\n\n\\`\\`\\`javascript\n// Get all students\nconst students = await client.students.list();\n\n// With pagination\nconst students = await client.students.list({\n  page: 1,\n  limit: 50\n});\n\n// With filters\nconst students = await client.students.list({\n  grade: '10',\n  status: 'active',\n  search: 'john'\n});\n\\`\\`\\`\n\n#### Get Student\n\n\\`\\`\\`javascript\nconst student = await client.students.get('student-id');\n\\`\\`\\`\n\n#### Create Student\n\n\\`\\`\\`javascript\nconst newStudent = await client.students.create({\n  firstName: 'John',\n  lastName: 'Doe',\n  email: 'john.doe@email.com',\n  grade: '10',\n  dateOfBirth: '2008-05-15',\n  address: {\n    street: '123 Main St',\n    city: 'Anytown',\n    state: 'CA',\n    zipCode: '12345'\n  },\n  parentContact: {\n    name: 'Jane Doe',\n    email: 'jane.doe@email.com',\n    phone: '+1-555-0123'\n  }\n});\n\\`\\`\\`\n\n#### Update Student\n\n\\`\\`\\`javascript\nconst updatedStudent = await client.students.update('student-id', {\n  grade: '11',\n  email: 'john.doe.updated@email.com'\n});\n\\`\\`\\`\n\n#### Delete Student\n\n\\`\\`\\`javascript\nawait client.students.delete('student-id');\n\\`\\`\\`\n\n### Teachers\n\n#### List Teachers\n\n\\`\\`\\`javascript\nconst teachers = await client.teachers.list({\n  department: 'Mathematics',\n  status: 'active'\n});\n\\`\\`\\`\n\n#### Create Teacher\n\n\\`\\`\\`javascript\nconst newTeacher = await client.teachers.create({\n  firstName: 'Sarah',\n  lastName: 'Johnson',\n  email: 'sarah.johnson@school.edu',\n  department: 'Mathematics',\n  subjects: ['Algebra', 'Geometry'],\n  hireDate: '2020-08-15',\n  qualifications: ['M.Ed Mathematics', 'B.S Mathematics']\n});\n\\`\\`\\`\n\n### Courses\n\n#### List Courses\n\n\\`\\`\\`javascript\nconst courses = await client.courses.list({\n  semester: 'Fall 2024',\n  department: 'Science'\n});\n\\`\\`\\`\n\n#### Create Course\n\n\\`\\`\\`javascript\nconst newCourse = await client.courses.create({\n  name: 'Advanced Biology',\n  code: 'BIO-401',\n  description: 'Advanced topics in biology',\n  credits: 4,\n  department: 'Science',\n  teacherId: 'teacher-id',\n  schedule: {\n    days: ['Monday', 'Wednesday', 'Friday'],\n    startTime: '09:00',\n    endTime: '10:30',\n    room: 'SCI-101'\n  },\n  semester: 'Fall 2024'\n});\n\\`\\`\\`\n\n### Enrollments\n\n#### List Enrollments\n\n\\`\\`\\`javascript\nconst enrollments = await client.enrollments.list({\n  studentId: 'student-id',\n  semester: 'Fall 2024'\n});\n\\`\\`\\`\n\n#### Enroll Student\n\n\\`\\`\\`javascript\nconst enrollment = await client.enrollments.create({\n  studentId: 'student-id',\n  courseId: 'course-id',\n  semester: 'Fall 2024',\n  enrollmentDate: '2024-08-15'\n});\n\\`\\`\\`\n\n### Grades\n\n#### List Grades\n\n\\`\\`\\`javascript\nconst grades = await client.grades.list({\n  studentId: 'student-id',\n  courseId: 'course-id',\n  semester: 'Fall 2024'\n});\n\\`\\`\\`\n\n#### Record Grade\n\n\\`\\`\\`javascript\nconst grade = await client.grades.create({\n  studentId: 'student-id',\n  courseId: 'course-id',\n  assignmentName: 'Midterm Exam',\n  score: 85,\n  maxScore: 100,\n  weight: 0.3,\n  category: 'exam',\n  gradedDate: '2024-10-15'\n});\n\\`\\`\\`\n\n### Attendance\n\n#### List Attendance\n\n\\`\\`\\`javascript\nconst attendance = await client.attendance.list({\n  studentId: 'student-id',\n  date: '2024-10-15'\n});\n\\`\\`\\`\n\n#### Record Attendance\n\n\\`\\`\\`javascript\nconst attendance = await client.attendance.create({\n  studentId: 'student-id',\n  courseId: 'course-id',\n  date: '2024-10-15',\n  status: 'present', // 'present', 'absent', 'tardy', 'excused'\n  notes: 'Arrived 5 minutes late'\n});\n\\`\\`\\`\n\n## 🚨 Error Handling\n\nThe SDK throws specific error types for different scenarios:\n\n\\`\\`\\`javascript\nimport { CampusIQError } from '@campusiq/sdk';\n\ntry {\n  const student = await client.students.get('invalid-id');\n} catch (error) {\n  if (error instanceof CampusIQError) {\n    console.log('Error Code:', error.code);\n    console.log('Error Message:', error.message);\n    console.log('HTTP Status:', error.status);\n    console.log('Request ID:', error.requestId);\n  }\n}\n\\`\\`\\`\n\n### Error Types\n\n- `ValidationError` - Invalid input data\n- `AuthenticationError` - Invalid API key or permissions\n- `NotFoundError` - Resource not found\n- `RateLimitError` - Rate limit exceeded\n- `ServerError` - Internal server error\n\n## 📄 Pagination\n\nAll list methods support pagination:\n\n\\`\\`\\`javascript\nconst students = await client.students.list({\n  page: 1,\n  limit: 25\n});\n\nconsole.log(students.data); // Array of students\nconsole.log(students.pagination); // Pagination info\n/*\n{\n  page: 1,\n  limit: 25,\n  total: 150,\n  pages: 6,\n  hasNext: true,\n  hasPrev: false\n}\n*/\n\\`\\`\\`\n\n### Iterating Through Pages\n\n\\`\\`\\`javascript\nlet page = 1;\nlet hasMore = true;\n\nwhile (hasMore) {\n  const result = await client.students.list({ page, limit: 50 });\n  \n  // Process students\n  result.data.forEach(student => {\n    console.log(student.firstName, student.lastName);\n  });\n  \n  hasMore = result.pagination.hasNext;\n  page++;\n}\n\\`\\`\\`\n\n## 🔍 Filtering & Search\n\n### Basic Filtering\n\n\\`\\`\\`javascript\nconst students = await client.students.list({\n  grade: '10',\n  status: 'active'\n});\n\\`\\`\\`\n\n### Search\n\n\\`\\`\\`javascript\nconst students = await client.students.list({\n  search: 'john doe'\n});\n\\`\\`\\`\n\n### Advanced Filtering\n\n\\`\\`\\`javascript\nconst students = await client.students.list({\n  grade: ['9', '10', '11'], // Multiple values\n  enrollmentDate: {\n    gte: '2024-01-01',\n    lte: '2024-12-31'\n  },\n  sort: 'lastName:asc'\n});\n\\`\\`\\`\n\n## 🔔 Webhooks\n\n### Setting Up Webhooks\n\n\\`\\`\\`javascript\n// Configure webhook endpoint\nconst webhook = await client.webhooks.create({\n  url: 'https://your-app.com/webhooks/campusiq',\n  events: ['student.created', 'student.updated', 'grade.created'],\n  secret: 'your-webhook-secret'\n});\n\\`\\`\\`\n\n### Webhook Events\n\n- `student.created` - New student enrolled\n- `student.updated` - Student information updated\n- `student.deleted` - Student removed\n- `teacher.created` - New teacher added\n- `course.created` - New course created\n- `enrollment.created` - Student enrolled in course\n- `grade.created` - New grade recorded\n- `attendance.created` - Attendance recorded\n\n### Verifying Webhooks\n\n\\`\\`\\`javascript\nimport { CampusIQClient } from '@campusiq/sdk';\n\n// In your webhook handler\napp.post('/webhooks/campusiq', (req, res) => {\n  const signature = req.headers['x-campusiq-signature'];\n  const payload = req.body;\n  \n  if (CampusIQ.verifyWebhook(payload, signature, 'your-webhook-secret')) {\n    // Process webhook\n    console.log('Event:', payload.event);\n    console.log('Data:', payload.data);\n    res.status(200).send('OK');\n  } else {\n    res.status(400).send('Invalid signature');\n  }\n});\n\\`\\`\\`\n\n## 📝 TypeScript Support\n\nThe SDK is written in TypeScript and includes full type definitions:\n\n\\`\\`\\`typescript\nimport { CampusIQClient, Student, Teacher, Course } from '@campusiq/sdk';\n\nconst client = new CampusIQ({\n  apiKey: 'your-api-key',\n  schoolId: 'your-school-id'\n});\n\n// Fully typed responses\nconst students: Student[] = await client.students.list();\nconst student: Student = await client.students.get('student-id');\n\n// Type-safe creation\nconst newStudent: Student = await client.students.create({\n  firstName: 'John',\n  lastName: 'Doe',\n  email: 'john@example.com',\n  grade: '10' // TypeScript will enforce valid grade values\n});\n\\`\\`\\`\n\n### Available Types\n\n\\`\\`\\`typescript\ninterface Student {\n  id: string;\n  firstName: string;\n  lastName: string;\n  email: string;\n  grade: string;\n  status: 'active' | 'inactive' | 'graduated';\n  dateOfBirth: string;\n  enrollmentDate: string;\n  address: Address;\n  parentContact: Contact;\n  createdAt: string;\n  updatedAt: string;\n}\n\ninterface Teacher {\n  id: string;\n  firstName: string;\n  lastName: string;\n  email: string;\n  department: string;\n  subjects: string[];\n  hireDate: string;\n  status: 'active' | 'inactive';\n  qualifications: string[];\n  createdAt: string;\n  updatedAt: string;\n}\n\n// ... and many more\n\\`\\`\\`\n\n## 💡 Examples\n\n### Complete Student Management Example\n\n\\`\\`\\`javascript\nimport { CampusIQClient } from '@campusiq/sdk';\n\nconst client = new CampusIQClient({\n  apiKey: process.env.CAMPUSIQ_API_KEY,\n  schoolId: process.env.CAMPUSIQ_SCHOOL_ID\n});\n\nasync function manageStudents() {\n  try {\n    // Create a new student\n    const newStudent = await client.students.create({\n      firstName: 'Alice',\n      lastName: 'Smith',\n      email: 'alice.smith@email.com',\n      grade: '9',\n      dateOfBirth: '2009-03-20',\n      address: {\n        street: '456 Oak Ave',\n        city: 'Springfield',\n        state: 'IL',\n        zipCode: '62701'\n      },\n      parentContact: {\n        name: 'Bob Smith',\n        email: 'bob.smith@email.com',\n        phone: '+1-555-0456'\n      }\n    });\n\n    console.log('Created student:', newStudent.id);\n\n    // Get all 9th grade students\n    const ninthGraders = await client.students.list({\n      grade: '9',\n      status: 'active'\n    });\n\n    console.log(`Found ${ninthGraders.data.length} 9th grade students`);\n\n    // Update student grade\n    const updatedStudent = await client.students.update(newStudent.id, {\n      grade: '10'\n    });\n\n    console.log('Updated student grade to:', updatedStudent.grade);\n\n  } catch (error) {\n    console.error('Error managing students:', error.message);\n  }\n}\n\nmanageStudents();\n\\`\\`\\`\n\n### Bulk Operations Example\n\n\\`\\`\\`javascript\nasync function bulkEnrollStudents() {\n  const courseId = 'course-123';\n  const studentIds = ['student-1', 'student-2', 'student-3'];\n\n  const enrollments = await Promise.all(\n    studentIds.map(studentId =>\n      client.enrollments.create({\n        studentId,\n        courseId,\n        semester: 'Fall 2024',\n        enrollmentDate: new Date().toISOString().split('T')[0]\n      })\n    )\n  );\n\n  console.log(`Enrolled ${enrollments.length} students in course`);\n}\n\\`\\`\\`\n\n### Grade Calculation Example\n\n\\`\\`\\`javascript\nasync function calculateGPA(studentId) {\n  const grades = await client.grades.list({\n    studentId,\n    semester: 'Fall 2024'\n  });\n\n  const totalPoints = grades.data.reduce((sum, grade) => {\n    const percentage = (grade.score / grade.maxScore) * 100;\n    const gpa = percentageToGPA(percentage);\n    return sum + (gpa * grade.credits);\n  }, 0);\n\n  const totalCredits = grades.data.reduce((sum, grade) => sum + grade.credits, 0);\n  const gpa = totalPoints / totalCredits;\n\n  console.log(`Student GPA: ${gpa.toFixed(2)}`);\n  return gpa;\n}\n\nfunction percentageToGPA(percentage) {\n  if (percentage >= 97) return 4.0;\n  if (percentage >= 93) return 3.7;\n  if (percentage >= 90) return 3.3;\n  if (percentage >= 87) return 3.0;\n  if (percentage >= 83) return 2.7;\n  if (percentage >= 80) return 2.3;\n  if (percentage >= 77) return 2.0;\n  if (percentage >= 73) return 1.7;\n  if (percentage >= 70) return 1.3;\n  if (percentage >= 67) return 1.0;\n  return 0.0;\n}\n\\`\\`\\`\n\n## 🔧 Advanced Configuration\n\n### Custom HTTP Client\n\n\\`\\`\\`javascript\nimport axios from 'axios';\n\nconst client = new CampusIQClient({\n  apiKey: 'your-api-key',\n  schoolId: 'your-school-id',\n  httpClient: axios.create({\n    timeout: 60000,\n    headers: {\n      'User-Agent': 'MyApp/1.0.0'\n    }\n  })\n});\n\\`\\`\\`\n\n### Request Interceptors\n\n\\`\\`\\`javascript\nclient.interceptors.request.use((config) => {\n  console.log('Making request to:', config.url);\n  return config;\n});\n\nclient.interceptors.response.use(\n  (response) => {\n    console.log('Response received:', response.status);\n    return response;\n  },\n  (error) => {\n    console.error('Request failed:', error.message);\n    return Promise.reject(error);\n  }\n);\n\\`\\`\\`\n\n### Rate Limiting\n\n\\`\\`\\`javascript\nconst client = new CampusIQClient({\n  apiKey: 'your-api-key',\n  schoolId: 'your-school-id',\n  rateLimit: {\n    requests: 100,\n    per: 'minute' // 'second', 'minute', 'hour'\n  }\n});\n\\`\\`\\`\n\n## 🧪 Testing\n\n### Mock Client for Testing\n\n\\`\\`\\`javascript\nimport { CampusIQClient } from '@campusiq/sdk';\n\n// Create a mock client for testing\nconst mockClient = new CampusIQClient({\n  apiKey: 'test-key',\n  schoolId: 'test-school',\n  environment: 'test'\n});\n\n// Mock responses\nmockClient.students.list = jest.fn().mockResolvedValue({\n  data: [\n    { id: '1', firstName: 'John', lastName: 'Doe' }\n  ],\n  pagination: { page: 1, total: 1 }\n});\n\\`\\`\\`\n\n### Integration Testing\n\n\\`\\`\\`javascript\ndescribe('CampusIQ SDK Integration', () => {\n  let client;\n\n  beforeAll(() => {\n    client = new CampusIQClient({\n      apiKey: process.env.TEST_API_KEY,\n      schoolId: process.env.TEST_SCHOOL_ID,\n      environment: 'sandbox'\n    });\n  });\n\n  test('should create and retrieve student', async () => {\n    const newStudent = await client.students.create({\n      firstName: 'Test',\n      lastName: 'Student',\n      email: 'test@example.com',\n      grade: '9'\n    });\n\n    expect(newStudent.id).toBeDefined();\n\n    const retrievedStudent = await client.students.get(newStudent.id);\n    expect(retrievedStudent.firstName).toBe('Test');\n  });\n});\n\\`\\`\\`\n\n## 📊 Performance Tips\n\n### Batch Operations\n\n\\`\\`\\`javascript\n// Instead of multiple individual requests\nconst students = [];\nfor (const data of studentData) {\n  const student = await client.students.create(data); // Slow\n  students.push(student);\n}\n\n// Use batch operations when available\nconst students = await client.students.createBatch(studentData); // Fast\n\\`\\`\\`\n\n### Efficient Pagination\n\n\\`\\`\\`javascript\n// Use cursors for large datasets\nlet cursor = null;\nconst allStudents = [];\n\ndo {\n  const result = await client.students.list({\n    limit: 100,\n    cursor\n  });\n  \n  allStudents.push(...result.data);\n  cursor = result.pagination.nextCursor;\n} while (cursor);\n\\`\\`\\`\n\n### Caching\n\n\\`\\`\\`javascript\nconst NodeCache = require('node-cache');\nconst cache = new NodeCache({ stdTTL: 300 }); // 5 minutes\n\nasync function getCachedStudent(id) {\n  const cacheKey = `student:${id}`;\n  let student = cache.get(cacheKey);\n  \n  if (!student) {\n    student = await client.students.get(id);\n    cache.set(cacheKey, student);\n  }\n  \n  return student;\n}\n\\`\\`\\`\n\n## 🛠️ Troubleshooting\n\n### Common Issues\n\n#### Authentication Errors\n\n\\`\\`\\`javascript\n// Check your API key format\nif (!apiKey.startsWith('ciq_')) {\n  throw new Error('Invalid API key format');\n}\n\n// Verify school ID\nif (!schoolId.match(/^[0-9a-f]{24}$/)) {\n  throw new Error('Invalid school ID format');\n}\n\\`\\`\\`\n\n#### Rate Limiting\n\n\\`\\`\\`javascript\ntry {\n  const result = await client.students.list();\n} catch (error) {\n  if (error.code === 'RATE_LIMIT_EXCEEDED') {\n    const retryAfter = error.retryAfter; // seconds\n    console.log(`Rate limited. Retry after ${retryAfter} seconds`);\n    \n    // Wait and retry\n    await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));\n    const result = await client.students.list();\n  }\n}\n\\`\\`\\`\n\n#### Network Issues\n\n\\`\\`\\`javascript\nconst client = new CampusIQClient({\n  apiKey: 'your-api-key',\n  schoolId: 'your-school-id',\n  retries: 3,\n  retryDelay: 1000, // 1 second\n  timeout: 30000 // 30 seconds\n});\n\\`\\`\\`\n\n### Debug Mode\n\n\\`\\`\\`javascript\nconst client = new CampusIQClient({\n  apiKey: 'your-api-key',\n  schoolId: 'your-school-id',\n  debug: true // Enable debug logging\n});\n\\`\\`\\`\n\n## 📞 Support\n\n- **Documentation**: [https://docs.campusiq.edu](https://docs.campusiq.edu)\n- **API Reference**: [https://api.campusiq.edu/docs](https://api.campusiq.edu/docs)\n- **Support Email**: [support@campusiq.edu](mailto:support@campusiq.edu)\n- **GitHub Issues**: [https://github.com/campusiq/sdk-js/issues](https://github.com/campusiq/sdk-js/issues)\n\n## 🤝 Contributing\n\nWe welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.\n\n### Development Setup\n\n\\`\\`\\`bash\ngit clone https://github.com/campusiq/sdk-js.git\ncd sdk-js\nnpm install\nnpm run build\nnpm test\n\\`\\`\\`\n\n### Running Tests\n\n\\`\\`\\`bash\n# Unit tests\nnpm test\n\n# Integration tests\nnpm run test:integration\n\n# Coverage\nnpm run test:coverage\n\\`\\`\\`\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 🔄 Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for a list of changes and version history.\n\n---\n\n**Made with ❤️ by the CampusIQ Team**\n\nFor more information, visit [https://campusiq.edu](https://campusiq.edu)\n","readmeFilename":"README.md"}