50 lines
4.0 KiB
Markdown
50 lines
4.0 KiB
Markdown
# 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
|
|
|
|
1. Copy `.env.example` to `.env` and use the default local values.
|
|
2. Start PostgreSQL with `docker compose -f docker-compose.dev.yml up -d postgres`.
|
|
3. Install dependencies with `npm install`.
|
|
4. Apply the versioned schema with `npm run db:migrate`.
|
|
5. Run the API with `npm run dev:api` and the frontend with `npm 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/courses` returns published courses.
|
|
- `GET /api/v1/courses/:courseId` returns one published course.
|
|
- `GET /api/v1/courses/me/learning` returns the authenticated learner's started courses, ordered by their last activity, with completion percentage.
|
|
- `GET /api/v1/courses/:courseId/progress` and `PUT /api/v1/lessons/:lessonId/progress` persist completion and watch position.
|
|
- `GET /api/v1/admin/audit-log` exposes the last 50 administrative actions to superadmins.
|
|
|
|
## Accounts and instructor access
|
|
|
|
- `POST /api/v1/auth/register` creates student accounts only.
|
|
- `POST /api/v1/auth/login` creates a seven-day signed session.
|
|
- `GET /api/v1/auth/me` restores an existing session.
|
|
- Public authentication endpoints are rate-limited per source IP. Configure `AUTH_RATE_LIMIT_MAX` and `AUTH_RATE_LIMIT_WINDOW_SECONDS` if the defaults (10 attempts / 15 minutes) do not fit your environment.
|
|
- `GET`, `POST`, `PATCH`, and `DELETE` under `/api/v1/manage/courses` require 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.
|