4.0 KiB
Backend foundation
The project now has a small API and a PostgreSQL schema. Video delivery is provider-neutral: lesson_media.provider and lesson_media.external_id describe an external provider without coupling lessons to Panda, Vimeo, or any other service.
Local setup
- Copy
.env.exampleto.envand use the default local values. - Start PostgreSQL with
docker compose -f docker-compose.dev.yml up -d postgres. - Install dependencies with
npm install. - Apply the versioned schema with
npm run db:migrate. - Run the API with
npm run dev:apiand the frontend withnpm run dev.
The API health endpoint is available at http://localhost:3001/api/v1/health and verifies its PostgreSQL connection. /api/v1/ready is kept as an equivalent readiness endpoint for infrastructure checks.
Current API
GET /api/v1/coursesreturns published courses.GET /api/v1/courses/:courseIdreturns one published course.GET /api/v1/courses/me/learningreturns the authenticated learner's started courses, ordered by their last activity, with completion percentage.GET /api/v1/courses/:courseId/progressandPUT /api/v1/lessons/:lessonId/progresspersist completion and watch position.GET /api/v1/admin/audit-logexposes the last 50 administrative actions to superadmins.
Accounts and instructor access
POST /api/v1/auth/registercreates student accounts only.POST /api/v1/auth/logincreates a seven-day signed session.GET /api/v1/auth/merestores an existing session.- Public authentication endpoints are rate-limited per source IP. Configure
AUTH_RATE_LIMIT_MAXandAUTH_RATE_LIMIT_WINDOW_SECONDSif the defaults (10 attempts / 15 minutes) do not fit your environment. GET,POST,PATCH, andDELETEunder/api/v1/manage/coursesrequire an instructor or administrator session. Instructors can manage only their own courses.
Courses can be saved as a draft or published. Drafts are visible only in the managing instructor's dashboard and are never exposed by public course endpoints. Existing lessons keep their IDs when a course is edited, preserving learner progress and comment history; a lesson with progress or comments cannot be removed.
To create the first local administrator, set SUPERADMIN_EMAIL, SUPERADMIN_PASSWORD, and optionally SUPERADMIN_NAME, then run npm run db:bootstrap-admin. In Docker/Portainer, the API runs this command automatically after migrations.
For local demos, npm run db:seed-demo-content imports the original frontend catalogue into PostgreSQL. It requires the bootstrap administrator to exist and skips courses already present.
Anonymous visitors can browse course and lesson information, but media and download links are removed from their response. A signed-in account is required to play lessons, download materials, track progress, or participate in discussion.
Provider boundaries
Videos remain provider-neutral through lesson_media.provider and lesson_media.external_id. The platform does not yet create signed playback URLs because that requires the chosen provider's credentials and API. Do not add a provider secret until Panda Video, Vimeo, or another provider has been selected. Invitations and password resets currently generate secure, expiring links for the superadmin to copy; email delivery will be connected once an email service is chosen.
Administrative operations
The superadmin page supports user activation/role changes, invitations, password reset links, user learning details, CSV export, platform metrics, and an immutable-style activity log. Audit records cover invitations, reset links, user updates, course publishing/drafts/archive, and instructor comment moderation.
CI/CD status
Gitea Actions validates every pull request and every push to main by installing locked dependencies, type-checking the frontend and API, and building the frontend. The workflow deliberately does not upload a build artifact: the current Gitea runner does not support upload-artifact@v4, and Portainer builds the deployment image directly from the repository.