TutorLoom
기업·대학·교육기관을 위한 학습 플랫폼, 무료 오픈소스이며 엔터프라이즈 버전 제공
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기View basic information about CUET Students
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗An independent index of Chittagong University of Engineering & Technology students: search by name or ID, browse every batch and department, or use the public JSON API.
Site https://cuet.sayed.app · API docs https://cuet.sayed.app/api
@astrojs/cloudflareCUET_students): the single source of truth for student data; no data files live in this reposrc/middleware.ts), API rate limit via the Workers rate-limiting bindingsrc/
lib/departments.ts department table, keyed by the ID's department digits
lib/db.ts all D1 queries
lib/api.ts JSON helpers, rate limiting, API response shapes
pages/ routes (pages + /api endpoints)
components/, layouts/
migrations/ D1 schema and data fixes (data imports are gitignored)
scripts/csv-to-sql.mjs CSV → D1 migration for importing a new batch
scripts/refresh-derived.sql rebuilds class_counts / name_words (see below)
D1 bills every row a query reads, and students has ~17K rows, so no request
path may scan it. Counts come from class_counts (one row per class) and name
search goes through the indexed name_words table. After changing students
by hand, run npm run db:refresh (imports made with csv-to-sql do it already).
IDs are YY DD RRR: batch, department code, class roll. The site and API take the department from DD, not from the
department text column. Code 12 shows as MSE for batches ≤ 22 and MME after that.
| Page | URL |
|---|---|
| Home | / |
| Search | /search?q=…&batch=25&dept=cse (a full ID redirects to the profile) |
| Batches | /batch, /batch/25, /batch/25/cse |
| Departments | /department, /department/cse |
| Student | /2504001 |
| API docs | /api |
Old URLs (/batch?department=…&batch=…, /search?name=…, sitemap_N.xml) redirect.
Read-only, no key, CORS *, 60 requests/minute per IP, responses cached up to 24 h.
| Endpoint | Returns |
|---|---|
GET /api/v1/students/{id} | one student |
GET /api/v1/search?q=&batch=&dept=&limit= | name search, or ID prefix if q is digits |
GET /api/v1/batches | batches with per-department counts |
GET /api/v1/batches/{batch}/{dept} | full class list |
GET /api/v1/departments | departments with their batches |
The legacy /api/student/{id} and /api/student/search?query= endpoints still answer in the old flat format. Full
reference with a live console: /api.
Node 22.12+ (.nvmrc pins 24).
npm install
npm run dev # http://localhost:4321 with a local D1
npm run check # wrangler types + astro check
npm run preview # build and run the real Worker locally
The local D1 starts empty. Copy production into it:
npx wrangler d1 export CUET_students --remote --output prod.sql
npx wrangler d1 execute CUET_students --local --file prod.sql
Cloudflare Workers Builds watches this repo:
main → npm run build → npx wrangler deploy (production)redirect) → preview version onlynpm run deploy deploys manually. Every deploy also clears the edge cache.
/sitemap.xml is a sitemap index: /sitemap-pages.xml (home, listings, batch/class/department pages) plus one
/sitemap-batch-YY.xml per batch with every profile. All entries carry <lastmod> from D1's updated_at.robots.txt allows everything except /search?… (search result pages are also noindex).WebSite + search action, Person, BreadcrumbList).cuet.sayed.app).node scripts/indexnow.mjs pushes every sitemap URL via IndexNow;
--since YYYY-MM-DD sends only changed pages. Key file: public/1144afef155385c08e4aca5b16ec8642.txt.studentid,name,admission_roll,admission_merit.node scripts/csv-to-sql.mjs batch26.csv migrations/0006_import_batch_26.sql
(use the next free migration number; the script appends scripts/refresh-derived.sql,
so class_counts and name_words update in the same migration)npm run db:migrate (applies new migrations to production D1)npx wrangler d1 execute CUET_students --remote --command "SELECT (SELECT COUNT(*) FROM students), (SELECT SUM(count) FROM class_counts), (SELECT COUNT(DISTINCT studentid) FROM name_words)"
If they differ, run npm run db:refresh.main so the edge cache and the in-memory overview refresh, then
node scripts/indexnow.mjs --since <today>.Import migrations contain personal data and are gitignored; keep the CSV outside the repo.
Any hand-made change to students (a fix migration, d1 execute, the dashboard) must be
followed by npm run db:refresh, or counts and search go stale:
db:refresh is enough.DELETE FROM name_words WHERE studentid = '2504001'; then db:refresh.DELETE FROM name_words WHERE studentid = ... (stale rows are
harmless for results, but waste reads).Don't rebuild name_words from scratch (DELETE FROM name_words + refresh): that is
~50K row writes, half the free daily limit.
D1 bills every row a query reads: 5M/day, then all queries fail until 00:00 UTC. A
query without an index on its WHERE reads all ~8.6K students (plus index rows). Before
adding a query, check its plan in wrangler d1 execute --local with EXPLAIN QUERY PLAN:
it must say SEARCH ... USING INDEX, never SCAN students. Usage per database:
dashboard → D1 → CUET_students → Metrics.
Avoid node scripts/indexnow.mjs without --since: it makes crawlers fetch every
profile at once (that, plus full-table scans, caused the Nov 2026 outage).
D1 keeps 30 days of point-in-time history (Time Travel). For an offline copy:
npx wrangler d1 export CUET_students --remote --output cuet-backup.sql
main: this siteredirect: the cuet.pages.dev Pages project, which redirects to cuet.sayed.apparchive/* tags: the old Next.js versionsData was compiled from publicly available sources and may contain errors. Personal use is free; commercial use or integration into another system requires acknowledgment. See privacy and terms. Contact: [email protected].
Built by Sayed.