Lexiverse
Lexiverse - AI contextual reading engine for English learners. Your next article is your next review.
翻訳待ち
UniLink is your comprehensive guide to private, public, and specialized universities in Egypt — programs, admission requirements, tuition fees, and scholarships in one place.
翻訳待ち
教育PLpgSQL · TypeScriptGitHub @Anu-bytesオンライン所有者未確認
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Loading the full README. The saved excerpt is shown below.
Web platform connecting students with universities and study-abroad programs.
• Next.js 16 (App Router, React 19) — apps/web
• Prisma 6 + PostgreSQL — database & ORM
• Auth.js (NextAuth v5) — credentials + Google OAuth
• next-intl — i18n with English & Arabic (RTL) locales
• Tailwind CSS v4 + shadcn / Base UI — styling & components
• npm workspaces — monorepo (apps/*)
• Node.js 20+
• Docker (for local PostgreSQL) — or a hosted Postgres connection string
Copy the example env files and fill in your own values:
Never commit .env files — they hold real credentials and are gitignored.Read the full README ↗Web platform connecting students with universities and study-abroad programs.
apps/webapps/*)unilink-workspace/
├─ apps/
│ └─ web/ # Next.js app (frontend + API routes)
│ ├─ prisma/ # schema.prisma, migrations, seed/
│ ├─ messages/ # i18n translation files (en.json, ar.json)
│ ├─ public/ # static assets
│ └─ src/ # app code (app/, components/, lib/, i18n/)
├─ compose.yaml # local PostgreSQL via Docker
└─ package.json # workspace root scripts
npm install
Copy the example env files and fill in your own values:
cp .env.example .env # database creds for docker compose
cp apps/web/.env.example apps/web/.env # app config (DATABASE_URL, AUTH_SECRET, OAuth)
Generate an auth secret with:
npx auth secret
Never commit
.envfiles — they hold real credentials and are gitignored.
For hosted Supabase, use the two connection strings shown by Supabase Dashboard > Connect:
DATABASE_URL: transaction pooler on port 6543, used by the running appDIRECT_URL: session pooler on port 5432, used by Prisma migrationsKeeping these separate prevents schema migrations from running through transaction pooling. Use placeholders in committed files and keep real credentials only in apps/web/.env.
For the default local Compose database, replace both database URLs in
apps/web/.env with postgresql://postgres:postgres@localhost:5432/unilink?schema=public.
These are local development credentials only. If you customize root .env
credentials or POSTGRES_PORT, make the app URLs match those values.
npm run db:up
Skip this step when using Supabase.
npm run db:deploy # apply existing migrations without generating new ones
npm run db:seed # load the Egyptian university catalogue
The seed is idempotent and only touches the universities it owns (matched by
slug), so it is safe to re-run after editing apps/web/prisma/seed/data.ts.
Use db:migrate only when intentionally authoring a schema change. Prisma does
not model the raw-SQL trigram search indexes; do not accept generated migrations
that drop them during routine setup.
npm run dev
npm run build uses Next's supported Webpack production builder. The optional
npm run build:turbo --workspace=apps/web retains Turbopack for environments that
support its worker-port requirements. Development still uses Turbopack.
| Route | What it is |
|---|---|
/{locale}/universities | Public directory of published universities |
/{locale}/universities/[slug] | University profile: gallery hero plus the About / Faculties / Location / Admission Requirements / Admission Criteria / Minimum Scores / Tuition Fees tabs (?tab= is linkable) |
/{locale}/universities/[slug]/programs/[programSlug] | Program profile |
/{locale}/app/search | Signed-in program search: natural-language search bar, filters, match-scored result cards |
/{locale}/app/compare | Side-by-side comparison of up to four programs |
/{locale}/app/applications, /app/saved, /app/profile | Student workspace |
/{locale}/admin | Admin dashboard: catalogue, people, growth (see below) |
Everything under /{locale}/app requires a session; src/proxy.ts redirects
anonymous visitors to /login.
/{locale}/admin is the back office. It is bilingual and RTL-aware like the
rest of the site, but styled as its own surface — dark sidebar, light content —
so there is never a doubt about which side of the product you are on.
| Section | Route | What it manages |
|---|---|---|
| Overview | /admin | Counts across the catalogue, people and leads, plus the newest applications, sign-ups and partnership leads |
| Universities | /admin/universities | The university record and its gallery images, feature bullets, tab content blocks and minimum scores |
| Faculties | /admin/faculties | Faculties under each university |
| Programs | /admin/programs | Programs, their intakes and their English requirements |
| Users | /admin/users | Accounts, roles and the onboarding profile behind each one |
| Applications | /admin/applications | Every student application and its status |
| Leads | /admin/leads | Partnership requests submitted from /contact |
| Testimonials | /admin/testimonials | Home-page testimonials |
| Scholarships | /admin/scholarships | Scholarship listings |
User.role decides. Three layers guard the surface, because one is not enough:
src/proxy.ts sends anonymous visitors to /login. It only sees the session
cookie, so it cannot tell an admin from a student.[locale]/(admin)/admin calls requireAdminPage() as its
first statement, which re-reads the row. A signed-in non-admin gets a 404
rather than a "forbidden" page — nothing links here, so confirming the route
exists would only help someone guessing./api/admin/* handler independently calls requireAdmin().This is the beginning of the README. Read the rest at the original. Read the full README ↗