Data Storage Schema
All IC Insight data is stored in chrome.storage.local. This page documents every key, its type, and its schema.
Index and Cache Keys
ICI_CACHE_INDEX
An index of all cached courses.
Record<courseKey, {
courseId: string; // same as courseKey
courseName: string;
lastUpdated: number; // Unix timestamp in ms
sourceUrl: string; // original IC page URL
}>
course:${classroomSectionID}
The full cached snapshot for one course.
{
snapshotTs: number; // Unix timestamp in ms of last cache write
snapshot: {
courseName: string;
overall: number; // overall grade percentage computed from all quarters
quarters: Quarter[];
};
raw: {
courseId: string;
courseName: string;
quarters: RawQuarter[]; // raw parsed model (not recomputed)
};
sourceUrl: string;
source: 'manual' | 'auto';
}
Quarter {
id: string; // 'Q1' | 'Q2' | 'Q3' | 'Q4'
name: string; // 'Quarter 1' … 'Quarter 4'
startDate: string; // 'MM/DD/YYYY' or ''
endDate: string;
categories: Category[];
}
Category {
id: string; // category ID from IC DOM (e.g. 'c0')
name: string;
weight: number | null;
avg: number; // recomputed category average %
assignments: Assignment[];
}
Assignment {
name: string;
earned: number | null;
possible: number | null;
ungraded: boolean;
dueDate?: string;
dueText?: string;
dropped?: true;
multiplier?: number; // only present when != 1
letterGrade?: string; // e.g. 'A+'; earned will be null when present
}
${courseKey}_BACKUP
A copy of the previous cache entry, written before each overwrite. Same schema as course:${id}. Used for manual rollback. Not automatically cleaned up.
Override Keys (per course)
PE_${courseKey}
Permanent score overrides for a course ("Pins").
Record<`${quarterId}||${catId}||${assignmentName}`, {
category_id: string;
quarter_id: string; // '' if no quarter context
name: string; // assignment name
earned: number;
possible: number;
}>
PA_${courseKey}
Permanent assignment additions for a course.
Array<{
category_id: string;
quarter_id: string;
category_name: string;
name: string;
earned: number;
possible: number;
}>
WI_${courseKey}
Temporary what-if state for a course.
{
adds: Array<{ category_id: string; quarter_id: string | null; name: string; earned: number; possible: number }>;
drops: Array<{ category_id: string; name: string }>;
edits: Array<{ category_id: string; name: string; earned: number; possible: number }>;
}
Scenarios
ICI_SCENARIOS_${courseKey}
Named what-if scenarios for a course.
Array<{
id: string; // 'scenario_${timestamp}_${random}'
name: string; // user-provided scenario name
createdAt: string; // ISO timestamp
modifiedAt: string;
adds: WhatIfAdd[];
drops: WhatIfDrop[];
edits: WhatIfEdit[];
}>
SEBI Preferences
sebiPrefs
Record<courseKey, Record<normalizedCategoryName, true>>
Where normalizedCategoryName = categoryName.toLowerCase().trim().
Example:
{
"course:12345": {
"homework": true,
"quizzes": true
}
}
sebiGlobalEnabled
boolean // defaults to true
When false, SEBI UI is hidden and sebiPrefs is cleared.
GPA & Scale
ICI_GPA_SCALE
Array<{ min: number; letter: string; gpa: number }>
// sorted descending by min
ICI_GPA_WEIGHTS
Record<courseKey, number> // default: 1.0, set to 0 to exclude from GPA
ICI_GPA_SETTINGS
{
scaleDefault: string; // 'us-4.0'
aplusAs433: boolean; // true → A+ = 4.33, false → A+ = 4.4
scaleOverrides: Record<string, any>;
weighting: {
mode: 'additive' | 'multiplicative';
bumps: {
AP: number; // default 1.0
IB: number; // default 1.0
Honors: number; // default 0.5
Regular: number; // default 0.0
};
};
rounding: {
mode: 'nearest' | 'up' | 'down';
digits: number; // default 3
};
}
ICI_PAST_REPORT_CARDS
Array<{
id: string; // 'rc_${year}_mp${mp}_${timestamp}_${random}'
title: string;
schoolYear: string;
markingPeriod: string;
issuedAt: string; // ISO timestamp
courses: Array<{
name: string;
teacher?: string;
finalMark: { kind: 'percent' | 'letter'; value: number | string };
credits: number;
weightType: 'Regular' | 'Honors' | 'AP' | 'IB';
}>;
}>
ICI_SCHEMA_VERSION
number // currently 1
History Snapshots
ICI_HISTORY_SNAPSHOTS
Record<courseKey, Array<{
id: string; // 'snapshot_${timestamp}_${random}'
capturedAtISO: string; // ISO timestamp
courseTitle: string;
userInitiated: boolean;
version: 3;
summary: {
overallPercent: number;
};
quarters: Quarter[]; // same Quarter type as cache
categories: Category[]; // fallback for flat-structure snapshots
}>>
Snapshots within each array are sorted ascending by capturedAtISO.
UI & Appearance
ICI_UI_STATE
{
x: number | null; // left offset in px (null → default right-aligned)
y: number | null; // top offset in px
w: number; // width in px (default 420)
h: number | null; // height in px (null → auto)
minimized: boolean;
prevX: number | null; // position before minimize
prevY: number | null;
prevW: number | null;
prevH: number | null;
}
ICI_USER_NAME
string // '' when user entered nothing at the prompt
ICI_THEME
'light' | 'dark' | 'system' // default: 'system'
ICI_COLOR_PALETTE
'green' | 'blue' | 'purple' | 'rose' | 'orange' // default: 'green'
ICI_FRESH_HOURS
number // default: 12
ICI_STALE_HOURS
number // default: 24
Dashboard Settings
ICI_DASHBOARD_SORT
{
mode: 'updated' | 'custom' | 'best-grades' | 'worst-grades';
customOrderByCourseKey: string[]; // course keys in desired order (real mode)
customOrderByCourseKeyFake: string[]; // course keys in desired order (fake/testing mode)
}
ICI_HIDDEN_COURSES
string[] // array of courseKeys to hide from Dashboard
Refresh Metadata
ICI_COURSE_REFRESH_META
Record<courseKey, {
lastRefreshedAt: string; // ISO timestamp
// ...additional retry metadata fields
}>
Developer / Debug
debugMode
boolean // enables [ICI] debug logging in console
memoryDebug
boolean // enables heap + DOM-node logging in console
ICI_FAKE_GRADES_ENABLED
boolean // default: false; enables testing mode with generated fake courses