Skip to content

Repository files navigation

sislib — CUHK-Shenzhen SIS automation & course arrangement (TypeScript)

TypeScript monorepo that (1) wraps every direct operation of the CUHK-Shenzhen Student Information System (Oracle PeopleSoft Campus Solutions, https://sis.cuhk.edu.cn), and (2) solves course timetables on top of it.

packages/cuhksz-sislib   all direct SIS operations (login, class search,
                         schedule, history, transcript, enrollment surface)
packages/sisarrange       pure scheduling solver (abstract catalog +
                         constraints → ranked timetables; no SIS knowledge)
apps/web                 SvelteKit frontend (setup → pool → solve → sync);
                         its server side owns cuhksz-sislib (/api endpoints,
                         load functions, form actions)

Every mechanism in docs/sis-mechanism.md was verified against the live system; the TS implementation is verified by the ported fixture tests (pnpm test) and a read-only live pass (node scripts/verify_live.mjs <passphrase>). Design docs live in docs/design/.

Quick start

pnpm install
pnpm build
pnpm typecheck
pnpm test

# log in once (interactive ADFS browser; requires `pnpm exec playwright install chromium`)
node -e "import('./packages/cuhksz-sislib/dist/index.js').then(async (m) => {
  const c = new m.SisClient(m.defaultConfig({ headless: false }), process.argv[1]);
  await c.login('user', 'password');
})" passphrase

# verify the saved session read-only against the live SIS
node scripts/verify_live.mjs <passphrase>

# run the web app (single process: pages + /api on http://localhost:5173)
pnpm dev

The Python-era session (if you have one) unlocks with the same passphrase — the encrypted session format is shared.

Library surface (cuhksz-sislib)

const client = new SisClient(defaultConfig({ allowMutations: false }), passphrase);

// reads
await client.listTerms();                 // Term[]
await client.listSubjects();              // [code, label][]
await client.searchClasses({ term, subject, openOnly, selectable,});
await client.getWeeklySchedule();
await client.getCourseHistory();
await client.getAppointments(term?);      // windows + term unit limits
await client.getExamSchedule(term?);
await client.getGrades(term?);
await client.getCart(term?);              // shopping cart contents
await client.listTranscriptTypes();
await client.getTranscript("UE01");       // PDF bytes
await client.getMyAcademics();
await client.getMyApplication();

// mutations — throw MutationsDisabledError unless allowMutations: true
await client.cartAddByClassNbr(term, "3317");
await client.cartValidate(term);
await client.cartEnroll(term);            // real enrollment
await client.enrollmentSubmit("drop");    // gated on allowUnverified

Solver:

import { solve, normalizeConstraints } from "@cuhksz/sisarrange";
const constraints = normalizeConstraints({ required: [...], pick: [...],
  maxUnits: 18, preferences: { freeDayBonus: 10 } });
const schedules = solve(catalog, constraints, { limit: 10 });

Repository layout

docs/                    mechanism notes, design docs, worklog
packages/cuhksz-sislib/  src/{api,features,peoplesoft,transport,models,protocol}
packages/sisarrange/     src/{model,constraints,solver,objective,validate,analyze,time,viability}
apps/web/                SvelteKit + Tailwind v4; src/routes/{api,…} server side,
                         src/lib state/adapter, solve Web Worker
scripts/                 live verification tools (read-only)

See AGENTS.md for the contributor guide and security rules.

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages