ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
Submit assignments through the PH Submission Portal API
Translation pending
AI summary · website content
EducationTypeScript · JavaScriptGitHub @fl9mdasifOnlineOwner 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
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Backend API for the Project Submission & Review Dashboard (Programming Hero Associate Web Instructor hiring task). Students submit assignment work for review; mentors approve or reject it and track their own review activity.
| Layer | Technology |
|---|---|
| Runtime | Node.js, Express 5, TypeScript (strict) |
| Database | PostgreSQL via Prisma ORM v5 |
| Auth | JWT, bcrypt password hashing, role-based access control (STUDENT, MENTOR) |
| Validation | Zod |
| Security | helmet, explicit CORS allowlist, rate limiting, input sanitization |
| Role | Password | |
|---|---|---|
| Mentor | [email protected] | Mentor@12345 |
| Student (demo) | [email protected] | Student@123 |
The mentor account is seeded automatically on server boot from MENTOR_EMAIL / MENTOR_PASSWORD in .env — it is never created through a public endpoint. Demo student accounts and sample submissions can be added with node seed-demo.js (see below).
npm install
cp .env.example .env
| Variable | Description |
|---|---|
DATABASE_URL | PostgreSQL connection string used by the running app |
DIRECT_URL | Non-pooled connection string, used only by prisma migrate/db push |
JWT_ACCESS_SECRET | Long random string signing access tokens |
JWT_ACCESS_EXPIRES_IN | Token lifetime, e.g. 1d |
BCRYPT_SALT_ROUND | Password hashing cost, e.g. 12 |
MENTOR_EMAIL / MENTOR_PASSWORD / MENTOR_NAME | Mentor account seeded on first boot |
CLIENT_URL | Deployed Next.js client origin, added to the CORS allowlist |
Using Supabase or any PgBouncer-fronted Postgres? Point
DATABASE_URLat the Transaction pooler (port6543, add?pgbouncer=true) for the running app, andDIRECT_URLat the Session pooler (port5432) for migrations. Transaction-mode pooling doesn't support the advisory locks Prisma Migrate needs, so schema changes must go throughDIRECT_URL.
npx prisma migrate dev --name init
Creates 4 demo students and 5 sample submissions spanning all statuses, useful for showcasing the dashboard without manual data entry:
node seed-demo.js
npm run dev
The API listens on http://localhost:5000 by default and seeds the mentor account on first boot.
npm run build # tsc -> dist/
npm start # node dist/server.js
Base URL: /api/v1 · Auth header: Authorization: <accessToken> (no Bearer prefix)
| Method | Path | Auth | Body |
|---|---|---|---|
POST | /auth/register | None | { name, email, password } — always creates a STUDENT; a role field in the body is ignored |
POST | /auth/login | None | { email, password } → { accessToken, user } |
| Method | Path | Auth | Description |
|---|---|---|---|
POST | /submissions | STUDENT | Create a submission. 409 if this student already has a submission for that assignmentNumber. |
PATCH | /submissions/:id | STUDENT | Edit your own submission — allowed exactly once. Resets status to PENDING and clears feedback for re-review. 403 if already edited. |
GET | /submissions/my | STUDENT | List your own submissions. |
GET | /submissions | MENTOR | ?status=PENDING|APPROVED|REJECTED&assignmentNumber=1-15&searchTerm=&page=1&limit=10 — search matches project name or student name/email. |
GET | /submissions/stats | MENTOR | { PENDING, APPROVED, REJECTED, total } |
PATCH | /submissions/:id/status | MENTOR | { status: "APPROVED" | "REJECTED", feedback? }. Logged to the activity trail. |
GET | /submissions/activity | MENTOR | Paginated log of the mentor's own approve/reject actions. |
List endpoints return:
{
"success": true,
"statusCode": 200,
"message": "...",
"meta": { "page": 1, "limit": 10, "total": 5, "totalPages": 1 },
"data": [...]
}
User { id, name, email, password, role: STUDENT|MENTOR }
Submission { id, assignmentNumber (1-15), projectName, repoUrl, liveLink?,
description, status: PENDING|APPROVED|REJECTED, feedback?,
edited (bool), studentId }
ActivityLog { id, mentorId, submissionId, action, detail, createdAt }
@@unique([studentId, assignmentNumber]) enforces one submission per student per assignment.edited flips to true on the student's first (and only permitted) edit.ActivityLog row for auditability.src/
app.ts, server.ts
config/ # single source of truth for env vars
db/seedMentor.ts # seeds the mentor account on boot
helpers/jwtHelpers.ts
shared/ # catchAsync, sendResponse, pick, paginationHelper, prisma client
app/
errors/ApiError.ts
middlewares/ # auth, validateRequest, rateLimiters, sanitizeInput, globalErrorHandler, notFound
modules/
auth/ # controller, service, routes, validation
submission/ # controller, service, routes, validation, interface
routes/index.ts # mounts every module under /api/v1
CLIENT_URL + localhost) — never origin: '*'.HS256 and an explicit algorithm whitelist on verify.globalErrorHandler maps ApiError, ZodError, and known Prisma errors to correct status codes (never a blanket 500), and never leaks stack traces when NODE_ENV=production./auth/* and POST /submissions to blunt spam/credential-stuffing.