TutorLoom
The learning platform for companies, colleges and training institutes. Free and open source, with an Enterprise edition.
Search CUET students by name or ID and browse every batch and department of Chittagong University of Engineering & Technology.
Translation pending
EducationAstro · TypeScriptGitHub @abusayed0206OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
View basic information about CUET Students
Translation pending
Taken from the repository README
Loading the full README.
Read the full 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.