diff --git a/.dockerignore b/.dockerignore index 09e0451..bfe1caa 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,6 @@ -node_modules +**/node_modules +.git .env *.log -package-lock.json docker-compose.yml .dockerignore diff --git a/.github/workflows/deploy-qas.yml b/.github/workflows/deploy-qas.yml index 98908e8..2b7f285 100644 --- a/.github/workflows/deploy-qas.yml +++ b/.github/workflows/deploy-qas.yml @@ -3,6 +3,11 @@ name: Deploy to Cloudflare on: push: branches: [qas] + paths: + - 'apps/api/**' + - 'docker-compose.yml' + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' workflow_dispatch: {} jobs: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 40bb840..5a5a63e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -3,6 +3,11 @@ name: Deploy to droplet on: push: branches: [main] + paths: + - 'apps/api/**' + - 'docker-compose.yml' + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' workflow_dispatch: {} jobs: diff --git a/.env-development b/apps/api/.env-development similarity index 100% rename from .env-development rename to apps/api/.env-development diff --git a/.env-production b/apps/api/.env-production similarity index 100% rename from .env-production rename to apps/api/.env-production diff --git a/.sequelizerc b/apps/api/.sequelizerc similarity index 100% rename from .sequelizerc rename to apps/api/.sequelizerc diff --git a/Dockerfile b/apps/api/Dockerfile similarity index 60% rename from Dockerfile rename to apps/api/Dockerfile index d90d2c5..fc6d226 100644 --- a/Dockerfile +++ b/apps/api/Dockerfile @@ -14,11 +14,17 @@ COPY --from=typst /usr/bin/typst /usr/local/bin/typst WORKDIR /app -# Install production dependencies only +# Workspace manifests first (cache-friendly), then a filtered install — +# pnpm needs every workspace package's manifest present to resolve the +# graph even though only apps/api's deps get installed here. COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ -RUN pnpm install --frozen-lockfile +COPY apps/api/package.json ./apps/api/package.json +COPY apps/web/package.json ./apps/web/package.json +RUN pnpm install --frozen-lockfile --filter api... -COPY . . +COPY apps/api ./apps/api + +WORKDIR /app/apps/api RUN chmod +x docker-entrypoint.sh diff --git a/README.md b/apps/api/README.md similarity index 100% rename from README.md rename to apps/api/README.md diff --git a/ROUTES.md b/apps/api/ROUTES.md similarity index 100% rename from ROUTES.md rename to apps/api/ROUTES.md diff --git a/config/database.cjs b/apps/api/config/database.cjs similarity index 100% rename from config/database.cjs rename to apps/api/config/database.cjs diff --git a/config/db.config.js b/apps/api/config/db.config.js similarity index 100% rename from config/db.config.js rename to apps/api/config/db.config.js diff --git a/config/garage.toml b/apps/api/config/garage.toml similarity index 100% rename from config/garage.toml rename to apps/api/config/garage.toml diff --git a/config/redis.config.js b/apps/api/config/redis.config.js similarity index 100% rename from config/redis.config.js rename to apps/api/config/redis.config.js diff --git a/controllers/admin/achievements.controller.js b/apps/api/controllers/admin/achievements.controller.js similarity index 100% rename from controllers/admin/achievements.controller.js rename to apps/api/controllers/admin/achievements.controller.js diff --git a/controllers/admin/advertisements.controller.js b/apps/api/controllers/admin/advertisements.controller.js similarity index 100% rename from controllers/admin/advertisements.controller.js rename to apps/api/controllers/admin/advertisements.controller.js diff --git a/controllers/admin/assets.controller.js b/apps/api/controllers/admin/assets.controller.js similarity index 100% rename from controllers/admin/assets.controller.js rename to apps/api/controllers/admin/assets.controller.js diff --git a/controllers/admin/categories.controller.js b/apps/api/controllers/admin/categories.controller.js similarity index 100% rename from controllers/admin/categories.controller.js rename to apps/api/controllers/admin/categories.controller.js diff --git a/controllers/admin/completion_requirements.controller.js b/apps/api/controllers/admin/completion_requirements.controller.js similarity index 100% rename from controllers/admin/completion_requirements.controller.js rename to apps/api/controllers/admin/completion_requirements.controller.js diff --git a/controllers/admin/course_reading_progress.controller.js b/apps/api/controllers/admin/course_reading_progress.controller.js similarity index 100% rename from controllers/admin/course_reading_progress.controller.js rename to apps/api/controllers/admin/course_reading_progress.controller.js diff --git a/controllers/admin/courses.controller.js b/apps/api/controllers/admin/courses.controller.js similarity index 100% rename from controllers/admin/courses.controller.js rename to apps/api/controllers/admin/courses.controller.js diff --git a/controllers/admin/dashboard.controller.js b/apps/api/controllers/admin/dashboard.controller.js similarity index 100% rename from controllers/admin/dashboard.controller.js rename to apps/api/controllers/admin/dashboard.controller.js diff --git a/controllers/admin/documentation/advertisements.md b/apps/api/controllers/admin/documentation/advertisements.md similarity index 100% rename from controllers/admin/documentation/advertisements.md rename to apps/api/controllers/admin/documentation/advertisements.md diff --git a/controllers/admin/documentation/assets.md b/apps/api/controllers/admin/documentation/assets.md similarity index 100% rename from controllers/admin/documentation/assets.md rename to apps/api/controllers/admin/documentation/assets.md diff --git a/controllers/admin/documentation/categories.md b/apps/api/controllers/admin/documentation/categories.md similarity index 100% rename from controllers/admin/documentation/categories.md rename to apps/api/controllers/admin/documentation/categories.md diff --git a/controllers/admin/documentation/courses.md b/apps/api/controllers/admin/documentation/courses.md similarity index 100% rename from controllers/admin/documentation/courses.md rename to apps/api/controllers/admin/documentation/courses.md diff --git a/controllers/admin/documentation/dashboard.md b/apps/api/controllers/admin/documentation/dashboard.md similarity index 100% rename from controllers/admin/documentation/dashboard.md rename to apps/api/controllers/admin/documentation/dashboard.md diff --git a/controllers/admin/documentation/landing_pages.md b/apps/api/controllers/admin/documentation/landing_pages.md similarity index 100% rename from controllers/admin/documentation/landing_pages.md rename to apps/api/controllers/admin/documentation/landing_pages.md diff --git a/controllers/admin/documentation/notifications.md b/apps/api/controllers/admin/documentation/notifications.md similarity index 100% rename from controllers/admin/documentation/notifications.md rename to apps/api/controllers/admin/documentation/notifications.md diff --git a/controllers/admin/documentation/products.md b/apps/api/controllers/admin/documentation/products.md similarity index 100% rename from controllers/admin/documentation/products.md rename to apps/api/controllers/admin/documentation/products.md diff --git a/controllers/admin/documentation/profile.md b/apps/api/controllers/admin/documentation/profile.md similarity index 100% rename from controllers/admin/documentation/profile.md rename to apps/api/controllers/admin/documentation/profile.md diff --git a/controllers/admin/documentation/tasks.md b/apps/api/controllers/admin/documentation/tasks.md similarity index 100% rename from controllers/admin/documentation/tasks.md rename to apps/api/controllers/admin/documentation/tasks.md diff --git a/controllers/admin/documentation/tiers.md b/apps/api/controllers/admin/documentation/tiers.md similarity index 100% rename from controllers/admin/documentation/tiers.md rename to apps/api/controllers/admin/documentation/tiers.md diff --git a/controllers/admin/documentation/user_activity.md b/apps/api/controllers/admin/documentation/user_activity.md similarity index 100% rename from controllers/admin/documentation/user_activity.md rename to apps/api/controllers/admin/documentation/user_activity.md diff --git a/controllers/admin/documentation/user_groups.md b/apps/api/controllers/admin/documentation/user_groups.md similarity index 100% rename from controllers/admin/documentation/user_groups.md rename to apps/api/controllers/admin/documentation/user_groups.md diff --git a/controllers/admin/documentation/users.md b/apps/api/controllers/admin/documentation/users.md similarity index 100% rename from controllers/admin/documentation/users.md rename to apps/api/controllers/admin/documentation/users.md diff --git a/controllers/admin/lessons.controller.js b/apps/api/controllers/admin/lessons.controller.js similarity index 100% rename from controllers/admin/lessons.controller.js rename to apps/api/controllers/admin/lessons.controller.js diff --git a/controllers/admin/media.controller.js b/apps/api/controllers/admin/media.controller.js similarity index 100% rename from controllers/admin/media.controller.js rename to apps/api/controllers/admin/media.controller.js diff --git a/controllers/admin/notification.controller.js b/apps/api/controllers/admin/notification.controller.js similarity index 100% rename from controllers/admin/notification.controller.js rename to apps/api/controllers/admin/notification.controller.js diff --git a/controllers/admin/notificationBroadcasts.controller.js b/apps/api/controllers/admin/notificationBroadcasts.controller.js similarity index 100% rename from controllers/admin/notificationBroadcasts.controller.js rename to apps/api/controllers/admin/notificationBroadcasts.controller.js diff --git a/controllers/admin/notificationSettings.controller.js b/apps/api/controllers/admin/notificationSettings.controller.js similarity index 100% rename from controllers/admin/notificationSettings.controller.js rename to apps/api/controllers/admin/notificationSettings.controller.js diff --git a/controllers/admin/products.controller.js b/apps/api/controllers/admin/products.controller.js similarity index 100% rename from controllers/admin/products.controller.js rename to apps/api/controllers/admin/products.controller.js diff --git a/controllers/admin/profile.controller.js b/apps/api/controllers/admin/profile.controller.js similarity index 100% rename from controllers/admin/profile.controller.js rename to apps/api/controllers/admin/profile.controller.js diff --git a/controllers/admin/task.controller.js b/apps/api/controllers/admin/task.controller.js similarity index 100% rename from controllers/admin/task.controller.js rename to apps/api/controllers/admin/task.controller.js diff --git a/controllers/admin/task_completion.controller.js b/apps/api/controllers/admin/task_completion.controller.js similarity index 100% rename from controllers/admin/task_completion.controller.js rename to apps/api/controllers/admin/task_completion.controller.js diff --git a/controllers/admin/tier_categories.controller.js b/apps/api/controllers/admin/tier_categories.controller.js similarity index 100% rename from controllers/admin/tier_categories.controller.js rename to apps/api/controllers/admin/tier_categories.controller.js diff --git a/controllers/admin/tier_policies.controller.js b/apps/api/controllers/admin/tier_policies.controller.js similarity index 100% rename from controllers/admin/tier_policies.controller.js rename to apps/api/controllers/admin/tier_policies.controller.js diff --git a/controllers/admin/tiers.controller.js b/apps/api/controllers/admin/tiers.controller.js similarity index 100% rename from controllers/admin/tiers.controller.js rename to apps/api/controllers/admin/tiers.controller.js diff --git a/controllers/admin/units.controller.js b/apps/api/controllers/admin/units.controller.js similarity index 100% rename from controllers/admin/units.controller.js rename to apps/api/controllers/admin/units.controller.js diff --git a/controllers/admin/user_activity.controller.js b/apps/api/controllers/admin/user_activity.controller.js similarity index 100% rename from controllers/admin/user_activity.controller.js rename to apps/api/controllers/admin/user_activity.controller.js diff --git a/controllers/admin/user_groups.controller.js b/apps/api/controllers/admin/user_groups.controller.js similarity index 100% rename from controllers/admin/user_groups.controller.js rename to apps/api/controllers/admin/user_groups.controller.js diff --git a/controllers/admin/users.controller.js b/apps/api/controllers/admin/users.controller.js similarity index 100% rename from controllers/admin/users.controller.js rename to apps/api/controllers/admin/users.controller.js diff --git a/controllers/auth.controller.js b/apps/api/controllers/auth.controller.js similarity index 100% rename from controllers/auth.controller.js rename to apps/api/controllers/auth.controller.js diff --git a/controllers/client/advertisements.controller.js b/apps/api/controllers/client/advertisements.controller.js similarity index 100% rename from controllers/client/advertisements.controller.js rename to apps/api/controllers/client/advertisements.controller.js diff --git a/controllers/client/certificate.controller.js b/apps/api/controllers/client/certificate.controller.js similarity index 100% rename from controllers/client/certificate.controller.js rename to apps/api/controllers/client/certificate.controller.js diff --git a/controllers/client/course_purchases.controller.js b/apps/api/controllers/client/course_purchases.controller.js similarity index 100% rename from controllers/client/course_purchases.controller.js rename to apps/api/controllers/client/course_purchases.controller.js diff --git a/controllers/client/course_reading_progress.controller.js b/apps/api/controllers/client/course_reading_progress.controller.js similarity index 100% rename from controllers/client/course_reading_progress.controller.js rename to apps/api/controllers/client/course_reading_progress.controller.js diff --git a/controllers/client/courses.controller.js b/apps/api/controllers/client/courses.controller.js similarity index 100% rename from controllers/client/courses.controller.js rename to apps/api/controllers/client/courses.controller.js diff --git a/controllers/client/media.controller.js b/apps/api/controllers/client/media.controller.js similarity index 100% rename from controllers/client/media.controller.js rename to apps/api/controllers/client/media.controller.js diff --git a/controllers/client/notification.controller.js b/apps/api/controllers/client/notification.controller.js similarity index 100% rename from controllers/client/notification.controller.js rename to apps/api/controllers/client/notification.controller.js diff --git a/controllers/client/profile.controller.js b/apps/api/controllers/client/profile.controller.js similarity index 100% rename from controllers/client/profile.controller.js rename to apps/api/controllers/client/profile.controller.js diff --git a/controllers/client/task.controller.js b/apps/api/controllers/client/task.controller.js similarity index 100% rename from controllers/client/task.controller.js rename to apps/api/controllers/client/task.controller.js diff --git a/controllers/client/task_download.controller.js b/apps/api/controllers/client/task_download.controller.js similarity index 100% rename from controllers/client/task_download.controller.js rename to apps/api/controllers/client/task_download.controller.js diff --git a/controllers/client/task_progress.controller.js b/apps/api/controllers/client/task_progress.controller.js similarity index 100% rename from controllers/client/task_progress.controller.js rename to apps/api/controllers/client/task_progress.controller.js diff --git a/controllers/client/task_upload.controller.js b/apps/api/controllers/client/task_upload.controller.js similarity index 100% rename from controllers/client/task_upload.controller.js rename to apps/api/controllers/client/task_upload.controller.js diff --git a/controllers/client/tiers.controller.js b/apps/api/controllers/client/tiers.controller.js similarity index 100% rename from controllers/client/tiers.controller.js rename to apps/api/controllers/client/tiers.controller.js diff --git a/controllers/client/units.controller.js b/apps/api/controllers/client/units.controller.js similarity index 100% rename from controllers/client/units.controller.js rename to apps/api/controllers/client/units.controller.js diff --git a/controllers/health.controller.js b/apps/api/controllers/health.controller.js similarity index 100% rename from controllers/health.controller.js rename to apps/api/controllers/health.controller.js diff --git a/controllers/public/media.controller.js b/apps/api/controllers/public/media.controller.js similarity index 100% rename from controllers/public/media.controller.js rename to apps/api/controllers/public/media.controller.js diff --git a/controllers/staff/groups.ctrl.js b/apps/api/controllers/staff/groups.ctrl.js similarity index 100% rename from controllers/staff/groups.ctrl.js rename to apps/api/controllers/staff/groups.ctrl.js diff --git a/controllers/staff/scores.ctrl.js b/apps/api/controllers/staff/scores.ctrl.js similarity index 100% rename from controllers/staff/scores.ctrl.js rename to apps/api/controllers/staff/scores.ctrl.js diff --git a/controllers/staff/tasks.ctrl.js b/apps/api/controllers/staff/tasks.ctrl.js similarity index 100% rename from controllers/staff/tasks.ctrl.js rename to apps/api/controllers/staff/tasks.ctrl.js diff --git a/controllers/staff/users.controller.js b/apps/api/controllers/staff/users.controller.js similarity index 100% rename from controllers/staff/users.controller.js rename to apps/api/controllers/staff/users.controller.js diff --git a/controllers/staff/users.ctrl.js b/apps/api/controllers/staff/users.ctrl.js similarity index 100% rename from controllers/staff/users.ctrl.js rename to apps/api/controllers/staff/users.ctrl.js diff --git a/cron/admin.cron.js b/apps/api/cron/admin.cron.js similarity index 100% rename from cron/admin.cron.js rename to apps/api/cron/admin.cron.js diff --git a/cron/client.cron.js b/apps/api/cron/client.cron.js similarity index 100% rename from cron/client.cron.js rename to apps/api/cron/client.cron.js diff --git a/cron/cronRegistry.util.js b/apps/api/cron/cronRegistry.util.js similarity index 100% rename from cron/cronRegistry.util.js rename to apps/api/cron/cronRegistry.util.js diff --git a/cron/jobs/expire_advertisements.cron.js b/apps/api/cron/jobs/expire_advertisements.cron.js similarity index 100% rename from cron/jobs/expire_advertisements.cron.js rename to apps/api/cron/jobs/expire_advertisements.cron.js diff --git a/cron/jobs/expire_user_tiers.cron.js b/apps/api/cron/jobs/expire_user_tiers.cron.js similarity index 100% rename from cron/jobs/expire_user_tiers.cron.js rename to apps/api/cron/jobs/expire_user_tiers.cron.js diff --git a/cron/jobs/fail_stale_payments.cron.js b/apps/api/cron/jobs/fail_stale_payments.cron.js similarity index 100% rename from cron/jobs/fail_stale_payments.cron.js rename to apps/api/cron/jobs/fail_stale_payments.cron.js diff --git a/cron/jobs/issue_certificates.cron.js b/apps/api/cron/jobs/issue_certificates.cron.js similarity index 100% rename from cron/jobs/issue_certificates.cron.js rename to apps/api/cron/jobs/issue_certificates.cron.js diff --git a/cron/jobs/lift_expired_bans.cron.js b/apps/api/cron/jobs/lift_expired_bans.cron.js similarity index 100% rename from cron/jobs/lift_expired_bans.cron.js rename to apps/api/cron/jobs/lift_expired_bans.cron.js diff --git a/cron/jobs/retry_stuck_transcodes.cron.js b/apps/api/cron/jobs/retry_stuck_transcodes.cron.js similarity index 100% rename from cron/jobs/retry_stuck_transcodes.cron.js rename to apps/api/cron/jobs/retry_stuck_transcodes.cron.js diff --git a/cron/jobs/task_due_soon.cron.js b/apps/api/cron/jobs/task_due_soon.cron.js similarity index 100% rename from cron/jobs/task_due_soon.cron.js rename to apps/api/cron/jobs/task_due_soon.cron.js diff --git a/cron/jobs/task_overdue.cron.js b/apps/api/cron/jobs/task_overdue.cron.js similarity index 100% rename from cron/jobs/task_overdue.cron.js rename to apps/api/cron/jobs/task_overdue.cron.js diff --git a/cron/jobs/user_notifications.cron.js b/apps/api/cron/jobs/user_notifications.cron.js similarity index 100% rename from cron/jobs/user_notifications.cron.js rename to apps/api/cron/jobs/user_notifications.cron.js diff --git a/data/achievements.data.js b/apps/api/data/achievements.data.js similarity index 100% rename from data/achievements.data.js rename to apps/api/data/achievements.data.js diff --git a/data/cronPresets.data.js b/apps/api/data/cronPresets.data.js similarity index 100% rename from data/cronPresets.data.js rename to apps/api/data/cronPresets.data.js diff --git a/data/email_body.data.js b/apps/api/data/email_body.data.js similarity index 100% rename from data/email_body.data.js rename to apps/api/data/email_body.data.js diff --git a/data/notifications.data.js b/apps/api/data/notifications.data.js similarity index 100% rename from data/notifications.data.js rename to apps/api/data/notifications.data.js diff --git a/database/migrations/20270101000001-create-users.js b/apps/api/database/migrations/20270101000001-create-users.js similarity index 100% rename from database/migrations/20270101000001-create-users.js rename to apps/api/database/migrations/20270101000001-create-users.js diff --git a/database/migrations/20270101000002-create-assets.js b/apps/api/database/migrations/20270101000002-create-assets.js similarity index 100% rename from database/migrations/20270101000002-create-assets.js rename to apps/api/database/migrations/20270101000002-create-assets.js diff --git a/database/migrations/20270101000003-create-user-groups.js b/apps/api/database/migrations/20270101000003-create-user-groups.js similarity index 100% rename from database/migrations/20270101000003-create-user-groups.js rename to apps/api/database/migrations/20270101000003-create-user-groups.js diff --git a/database/migrations/20270101000004-create-user-sessions.js b/apps/api/database/migrations/20270101000004-create-user-sessions.js similarity index 100% rename from database/migrations/20270101000004-create-user-sessions.js rename to apps/api/database/migrations/20270101000004-create-user-sessions.js diff --git a/database/migrations/20270101000005-create-user-group-members.js b/apps/api/database/migrations/20270101000005-create-user-group-members.js similarity index 100% rename from database/migrations/20270101000005-create-user-group-members.js rename to apps/api/database/migrations/20270101000005-create-user-group-members.js diff --git a/database/migrations/20270101000006-create-achievements.js b/apps/api/database/migrations/20270101000006-create-achievements.js similarity index 100% rename from database/migrations/20270101000006-create-achievements.js rename to apps/api/database/migrations/20270101000006-create-achievements.js diff --git a/database/migrations/20270101000007-create-categories.js b/apps/api/database/migrations/20270101000007-create-categories.js similarity index 100% rename from database/migrations/20270101000007-create-categories.js rename to apps/api/database/migrations/20270101000007-create-categories.js diff --git a/database/migrations/20270101000008-create-courses.js b/apps/api/database/migrations/20270101000008-create-courses.js similarity index 100% rename from database/migrations/20270101000008-create-courses.js rename to apps/api/database/migrations/20270101000008-create-courses.js diff --git a/database/migrations/20270101000009-create-course-objectives.js b/apps/api/database/migrations/20270101000009-create-course-objectives.js similarity index 100% rename from database/migrations/20270101000009-create-course-objectives.js rename to apps/api/database/migrations/20270101000009-create-course-objectives.js diff --git a/database/migrations/20270101000010-create-course-prerequisites.js b/apps/api/database/migrations/20270101000010-create-course-prerequisites.js similarity index 100% rename from database/migrations/20270101000010-create-course-prerequisites.js rename to apps/api/database/migrations/20270101000010-create-course-prerequisites.js diff --git a/database/migrations/20270101000011-create-course-assessments.js b/apps/api/database/migrations/20270101000011-create-course-assessments.js similarity index 100% rename from database/migrations/20270101000011-create-course-assessments.js rename to apps/api/database/migrations/20270101000011-create-course-assessments.js diff --git a/database/migrations/20270101000012-create-units.js b/apps/api/database/migrations/20270101000012-create-units.js similarity index 100% rename from database/migrations/20270101000012-create-units.js rename to apps/api/database/migrations/20270101000012-create-units.js diff --git a/database/migrations/20270101000013-create-unit-quizzes.js b/apps/api/database/migrations/20270101000013-create-unit-quizzes.js similarity index 100% rename from database/migrations/20270101000013-create-unit-quizzes.js rename to apps/api/database/migrations/20270101000013-create-unit-quizzes.js diff --git a/database/migrations/20270101000014-create-lessons.js b/apps/api/database/migrations/20270101000014-create-lessons.js similarity index 100% rename from database/migrations/20270101000014-create-lessons.js rename to apps/api/database/migrations/20270101000014-create-lessons.js diff --git a/database/migrations/20270101000015-create-lesson-pages.js b/apps/api/database/migrations/20270101000015-create-lesson-pages.js similarity index 100% rename from database/migrations/20270101000015-create-lesson-pages.js rename to apps/api/database/migrations/20270101000015-create-lesson-pages.js diff --git a/database/migrations/20270101000016-create-lesson-objectives.js b/apps/api/database/migrations/20270101000016-create-lesson-objectives.js similarity index 100% rename from database/migrations/20270101000016-create-lesson-objectives.js rename to apps/api/database/migrations/20270101000016-create-lesson-objectives.js diff --git a/database/migrations/20270101000017-create-quiz-questions.js b/apps/api/database/migrations/20270101000017-create-quiz-questions.js similarity index 100% rename from database/migrations/20270101000017-create-quiz-questions.js rename to apps/api/database/migrations/20270101000017-create-quiz-questions.js diff --git a/database/migrations/20270101000018-create-quiz-options.js b/apps/api/database/migrations/20270101000018-create-quiz-options.js similarity index 100% rename from database/migrations/20270101000018-create-quiz-options.js rename to apps/api/database/migrations/20270101000018-create-quiz-options.js diff --git a/database/migrations/20270101000019-create-products.js b/apps/api/database/migrations/20270101000019-create-products.js similarity index 100% rename from database/migrations/20270101000019-create-products.js rename to apps/api/database/migrations/20270101000019-create-products.js diff --git a/database/migrations/20270101000020-create-course-purchases.js b/apps/api/database/migrations/20270101000020-create-course-purchases.js similarity index 100% rename from database/migrations/20270101000020-create-course-purchases.js rename to apps/api/database/migrations/20270101000020-create-course-purchases.js diff --git a/database/migrations/20270101000021-create-course-product-categories.js b/apps/api/database/migrations/20270101000021-create-course-product-categories.js similarity index 100% rename from database/migrations/20270101000021-create-course-product-categories.js rename to apps/api/database/migrations/20270101000021-create-course-product-categories.js diff --git a/database/migrations/20270101000022-create-course-roles.js b/apps/api/database/migrations/20270101000022-create-course-roles.js similarity index 100% rename from database/migrations/20270101000022-create-course-roles.js rename to apps/api/database/migrations/20270101000022-create-course-roles.js diff --git a/database/migrations/20270101000023-create-tier-categories.js b/apps/api/database/migrations/20270101000023-create-tier-categories.js similarity index 100% rename from database/migrations/20270101000023-create-tier-categories.js rename to apps/api/database/migrations/20270101000023-create-tier-categories.js diff --git a/database/migrations/20270101000024-create-tier-plans.js b/apps/api/database/migrations/20270101000024-create-tier-plans.js similarity index 100% rename from database/migrations/20270101000024-create-tier-plans.js rename to apps/api/database/migrations/20270101000024-create-tier-plans.js diff --git a/database/migrations/20270101000025-create-plan-courses.js b/apps/api/database/migrations/20270101000025-create-plan-courses.js similarity index 100% rename from database/migrations/20270101000025-create-plan-courses.js rename to apps/api/database/migrations/20270101000025-create-plan-courses.js diff --git a/database/migrations/20270101000026-create-user-tiers.js b/apps/api/database/migrations/20270101000026-create-user-tiers.js similarity index 100% rename from database/migrations/20270101000026-create-user-tiers.js rename to apps/api/database/migrations/20270101000026-create-user-tiers.js diff --git a/database/migrations/20270101000027-create-payments.js b/apps/api/database/migrations/20270101000027-create-payments.js similarity index 100% rename from database/migrations/20270101000027-create-payments.js rename to apps/api/database/migrations/20270101000027-create-payments.js diff --git a/database/migrations/20270101000028-create-plan-policies.js b/apps/api/database/migrations/20270101000028-create-plan-policies.js similarity index 100% rename from database/migrations/20270101000028-create-plan-policies.js rename to apps/api/database/migrations/20270101000028-create-plan-policies.js diff --git a/database/migrations/20270101000029-create-payment-policies.js b/apps/api/database/migrations/20270101000029-create-payment-policies.js similarity index 100% rename from database/migrations/20270101000029-create-payment-policies.js rename to apps/api/database/migrations/20270101000029-create-payment-policies.js diff --git a/database/migrations/20270101000030-create-system-badges.js b/apps/api/database/migrations/20270101000030-create-system-badges.js similarity index 100% rename from database/migrations/20270101000030-create-system-badges.js rename to apps/api/database/migrations/20270101000030-create-system-badges.js diff --git a/database/migrations/20270101000031-create-quiz-attempts.js b/apps/api/database/migrations/20270101000031-create-quiz-attempts.js similarity index 100% rename from database/migrations/20270101000031-create-quiz-attempts.js rename to apps/api/database/migrations/20270101000031-create-quiz-attempts.js diff --git a/database/migrations/20270101000032-create-advertisements.js b/apps/api/database/migrations/20270101000032-create-advertisements.js similarity index 100% rename from database/migrations/20270101000032-create-advertisements.js rename to apps/api/database/migrations/20270101000032-create-advertisements.js diff --git a/database/migrations/20270101000033-create-task-lists.js b/apps/api/database/migrations/20270101000033-create-task-lists.js similarity index 100% rename from database/migrations/20270101000033-create-task-lists.js rename to apps/api/database/migrations/20270101000033-create-task-lists.js diff --git a/database/migrations/20270101000034-create-task-list-groups.js b/apps/api/database/migrations/20270101000034-create-task-list-groups.js similarity index 100% rename from database/migrations/20270101000034-create-task-list-groups.js rename to apps/api/database/migrations/20270101000034-create-task-list-groups.js diff --git a/database/migrations/20270101000035-create-tasks.js b/apps/api/database/migrations/20270101000035-create-tasks.js similarity index 100% rename from database/migrations/20270101000035-create-tasks.js rename to apps/api/database/migrations/20270101000035-create-tasks.js diff --git a/database/migrations/20270101000036-create-task-requirements.js b/apps/api/database/migrations/20270101000036-create-task-requirements.js similarity index 100% rename from database/migrations/20270101000036-create-task-requirements.js rename to apps/api/database/migrations/20270101000036-create-task-requirements.js diff --git a/database/migrations/20270101000037-create-task-completions.js b/apps/api/database/migrations/20270101000037-create-task-completions.js similarity index 100% rename from database/migrations/20270101000037-create-task-completions.js rename to apps/api/database/migrations/20270101000037-create-task-completions.js diff --git a/database/migrations/20270101000038-create-task-completion-files.js b/apps/api/database/migrations/20270101000038-create-task-completion-files.js similarity index 100% rename from database/migrations/20270101000038-create-task-completion-files.js rename to apps/api/database/migrations/20270101000038-create-task-completion-files.js diff --git a/database/migrations/20270101000039-create-task-link-visits.js b/apps/api/database/migrations/20270101000039-create-task-link-visits.js similarity index 100% rename from database/migrations/20270101000039-create-task-link-visits.js rename to apps/api/database/migrations/20270101000039-create-task-link-visits.js diff --git a/database/migrations/20270101000040-create-task-progress.js b/apps/api/database/migrations/20270101000040-create-task-progress.js similarity index 100% rename from database/migrations/20270101000040-create-task-progress.js rename to apps/api/database/migrations/20270101000040-create-task-progress.js diff --git a/database/migrations/20270101000041-create-task-prerequisites.js b/apps/api/database/migrations/20270101000041-create-task-prerequisites.js similarity index 100% rename from database/migrations/20270101000041-create-task-prerequisites.js rename to apps/api/database/migrations/20270101000041-create-task-prerequisites.js diff --git a/database/migrations/20270101000042-create-notification-broadcasts.js b/apps/api/database/migrations/20270101000042-create-notification-broadcasts.js similarity index 100% rename from database/migrations/20270101000042-create-notification-broadcasts.js rename to apps/api/database/migrations/20270101000042-create-notification-broadcasts.js diff --git a/database/migrations/20270101000043-create-admin-notifications.js b/apps/api/database/migrations/20270101000043-create-admin-notifications.js similarity index 100% rename from database/migrations/20270101000043-create-admin-notifications.js rename to apps/api/database/migrations/20270101000043-create-admin-notifications.js diff --git a/database/migrations/20270101000044-create-user-notifications.js b/apps/api/database/migrations/20270101000044-create-user-notifications.js similarity index 100% rename from database/migrations/20270101000044-create-user-notifications.js rename to apps/api/database/migrations/20270101000044-create-user-notifications.js diff --git a/database/migrations/20270101000045-create-course-reading-progress.js b/apps/api/database/migrations/20270101000045-create-course-reading-progress.js similarity index 100% rename from database/migrations/20270101000045-create-course-reading-progress.js rename to apps/api/database/migrations/20270101000045-create-course-reading-progress.js diff --git a/database/migrations/20270101000046-create-course-units.js b/apps/api/database/migrations/20270101000046-create-course-units.js similarity index 100% rename from database/migrations/20270101000046-create-course-units.js rename to apps/api/database/migrations/20270101000046-create-course-units.js diff --git a/database/migrations/20270101000047-create-unit-lessons.js b/apps/api/database/migrations/20270101000047-create-unit-lessons.js similarity index 100% rename from database/migrations/20270101000047-create-unit-lessons.js rename to apps/api/database/migrations/20270101000047-create-unit-lessons.js diff --git a/database/migrations/20270101000048-create-unit-reading-progress.js b/apps/api/database/migrations/20270101000048-create-unit-reading-progress.js similarity index 100% rename from database/migrations/20270101000048-create-unit-reading-progress.js rename to apps/api/database/migrations/20270101000048-create-unit-reading-progress.js diff --git a/database/migrations/20270101000049-create-lesson-reading-progress.js b/apps/api/database/migrations/20270101000049-create-lesson-reading-progress.js similarity index 100% rename from database/migrations/20270101000049-create-lesson-reading-progress.js rename to apps/api/database/migrations/20270101000049-create-lesson-reading-progress.js diff --git a/database/migrations/20270101000050-create-pages.js b/apps/api/database/migrations/20270101000050-create-pages.js similarity index 100% rename from database/migrations/20270101000050-create-pages.js rename to apps/api/database/migrations/20270101000050-create-pages.js diff --git a/database/migrations/20270101000051-create-landing-pages.js b/apps/api/database/migrations/20270101000051-create-landing-pages.js similarity index 100% rename from database/migrations/20270101000051-create-landing-pages.js rename to apps/api/database/migrations/20270101000051-create-landing-pages.js diff --git a/database/migrations/20270101000052-create-page-sections.js b/apps/api/database/migrations/20270101000052-create-page-sections.js similarity index 100% rename from database/migrations/20270101000052-create-page-sections.js rename to apps/api/database/migrations/20270101000052-create-page-sections.js diff --git a/database/migrations/20270101000053-create-page-blocks.js b/apps/api/database/migrations/20270101000053-create-page-blocks.js similarity index 100% rename from database/migrations/20270101000053-create-page-blocks.js rename to apps/api/database/migrations/20270101000053-create-page-blocks.js diff --git a/database/migrations/20270101000054-create-page-templates.js b/apps/api/database/migrations/20270101000054-create-page-templates.js similarity index 100% rename from database/migrations/20270101000054-create-page-templates.js rename to apps/api/database/migrations/20270101000054-create-page-templates.js diff --git a/database/migrations/20270101000055-create-announcements.js b/apps/api/database/migrations/20270101000055-create-announcements.js similarity index 100% rename from database/migrations/20270101000055-create-announcements.js rename to apps/api/database/migrations/20270101000055-create-announcements.js diff --git a/database/migrations/20270101000056-create-announcement-courses.js b/apps/api/database/migrations/20270101000056-create-announcement-courses.js similarity index 100% rename from database/migrations/20270101000056-create-announcement-courses.js rename to apps/api/database/migrations/20270101000056-create-announcement-courses.js diff --git a/database/migrations/20270101000057-create-announcement-roles.js b/apps/api/database/migrations/20270101000057-create-announcement-roles.js similarity index 100% rename from database/migrations/20270101000057-create-announcement-roles.js rename to apps/api/database/migrations/20270101000057-create-announcement-roles.js diff --git a/database/migrations/20270101000058-create-announcement-reads.js b/apps/api/database/migrations/20270101000058-create-announcement-reads.js similarity index 100% rename from database/migrations/20270101000058-create-announcement-reads.js rename to apps/api/database/migrations/20270101000058-create-announcement-reads.js diff --git a/database/migrations/20270101000059-create-user-activity.js b/apps/api/database/migrations/20270101000059-create-user-activity.js similarity index 100% rename from database/migrations/20270101000059-create-user-activity.js rename to apps/api/database/migrations/20270101000059-create-user-activity.js diff --git a/database/migrations/20270101000060-create-page-user-groups.js b/apps/api/database/migrations/20270101000060-create-page-user-groups.js similarity index 100% rename from database/migrations/20270101000060-create-page-user-groups.js rename to apps/api/database/migrations/20270101000060-create-page-user-groups.js diff --git a/database/migrations/20270101000061-create-assessment-sessions.js b/apps/api/database/migrations/20270101000061-create-assessment-sessions.js similarity index 100% rename from database/migrations/20270101000061-create-assessment-sessions.js rename to apps/api/database/migrations/20270101000061-create-assessment-sessions.js diff --git a/database/migrations/20270101000062-create-pending-certificates.js b/apps/api/database/migrations/20270101000062-create-pending-certificates.js similarity index 100% rename from database/migrations/20270101000062-create-pending-certificates.js rename to apps/api/database/migrations/20270101000062-create-pending-certificates.js diff --git a/database/migrations/20270101000063-create-cron-notification-settings.js b/apps/api/database/migrations/20270101000063-create-cron-notification-settings.js similarity index 100% rename from database/migrations/20270101000063-create-cron-notification-settings.js rename to apps/api/database/migrations/20270101000063-create-cron-notification-settings.js diff --git a/database/migrations/20270101000064-create-achievement-definitions.js b/apps/api/database/migrations/20270101000064-create-achievement-definitions.js similarity index 100% rename from database/migrations/20270101000064-create-achievement-definitions.js rename to apps/api/database/migrations/20270101000064-create-achievement-definitions.js diff --git a/database/migrations/20270101000065-create-trusted-devices.js b/apps/api/database/migrations/20270101000065-create-trusted-devices.js similarity index 100% rename from database/migrations/20270101000065-create-trusted-devices.js rename to apps/api/database/migrations/20270101000065-create-trusted-devices.js diff --git a/database/migrations/20270101000066-create-sticky-banner-settings.js b/apps/api/database/migrations/20270101000066-create-sticky-banner-settings.js similarity index 100% rename from database/migrations/20270101000066-create-sticky-banner-settings.js rename to apps/api/database/migrations/20270101000066-create-sticky-banner-settings.js diff --git a/database/migrations/20270101000067-create-completion-requirements.js b/apps/api/database/migrations/20270101000067-create-completion-requirements.js similarity index 100% rename from database/migrations/20270101000067-create-completion-requirements.js rename to apps/api/database/migrations/20270101000067-create-completion-requirements.js diff --git a/database/migrations/20270101000068-create-completion-requirement-progress.js b/apps/api/database/migrations/20270101000068-create-completion-requirement-progress.js similarity index 100% rename from database/migrations/20270101000068-create-completion-requirement-progress.js rename to apps/api/database/migrations/20270101000068-create-completion-requirement-progress.js diff --git a/database/migrations/20270101000069-create-certificates.js b/apps/api/database/migrations/20270101000069-create-certificates.js similarity index 100% rename from database/migrations/20270101000069-create-certificates.js rename to apps/api/database/migrations/20270101000069-create-certificates.js diff --git a/database/migrations/20270101000070-create-course-instructors.js b/apps/api/database/migrations/20270101000070-create-course-instructors.js similarity index 100% rename from database/migrations/20270101000070-create-course-instructors.js rename to apps/api/database/migrations/20270101000070-create-course-instructors.js diff --git a/database/migrations/20270101000071-create-quiz-sessions.js b/apps/api/database/migrations/20270101000071-create-quiz-sessions.js similarity index 100% rename from database/migrations/20270101000071-create-quiz-sessions.js rename to apps/api/database/migrations/20270101000071-create-quiz-sessions.js diff --git a/database/migrations/20270101000072-create-user-bans.js b/apps/api/database/migrations/20270101000072-create-user-bans.js similarity index 100% rename from database/migrations/20270101000072-create-user-bans.js rename to apps/api/database/migrations/20270101000072-create-user-bans.js diff --git a/database/migrations/20270101000073-create-media-playback-positions.js b/apps/api/database/migrations/20270101000073-create-media-playback-positions.js similarity index 100% rename from database/migrations/20270101000073-create-media-playback-positions.js rename to apps/api/database/migrations/20270101000073-create-media-playback-positions.js diff --git a/database/migrations/20270101000074-create-course-achievements.js b/apps/api/database/migrations/20270101000074-create-course-achievements.js similarity index 100% rename from database/migrations/20270101000074-create-course-achievements.js rename to apps/api/database/migrations/20270101000074-create-course-achievements.js diff --git a/database/migrations/20270101000075-add-user-tiers-active-per-tier-unique-index.js b/apps/api/database/migrations/20270101000075-add-user-tiers-active-per-tier-unique-index.js similarity index 100% rename from database/migrations/20270101000075-add-user-tiers-active-per-tier-unique-index.js rename to apps/api/database/migrations/20270101000075-add-user-tiers-active-per-tier-unique-index.js diff --git a/database/migrations/20270101000076-add-assets-transcode-status.js b/apps/api/database/migrations/20270101000076-add-assets-transcode-status.js similarity index 100% rename from database/migrations/20270101000076-add-assets-transcode-status.js rename to apps/api/database/migrations/20270101000076-add-assets-transcode-status.js diff --git a/database/migrations/20270101000077-add-lessons-subscription.js b/apps/api/database/migrations/20270101000077-add-lessons-subscription.js similarity index 100% rename from database/migrations/20270101000077-add-lessons-subscription.js rename to apps/api/database/migrations/20270101000077-add-lessons-subscription.js diff --git a/database/migrations/20270101000078-generalize-products-purchasable.js b/apps/api/database/migrations/20270101000078-generalize-products-purchasable.js similarity index 100% rename from database/migrations/20270101000078-generalize-products-purchasable.js rename to apps/api/database/migrations/20270101000078-generalize-products-purchasable.js diff --git a/database/migrations/20270101000079-create-plan-units.js b/apps/api/database/migrations/20270101000079-create-plan-units.js similarity index 100% rename from database/migrations/20270101000079-create-plan-units.js rename to apps/api/database/migrations/20270101000079-create-plan-units.js diff --git a/database/migrations/20270101000080-create-plan-lessons.js b/apps/api/database/migrations/20270101000080-create-plan-lessons.js similarity index 100% rename from database/migrations/20270101000080-create-plan-lessons.js rename to apps/api/database/migrations/20270101000080-create-plan-lessons.js diff --git a/database/migrations/20270101000081-add-tier-plans-audit-columns.js b/apps/api/database/migrations/20270101000081-add-tier-plans-audit-columns.js similarity index 100% rename from database/migrations/20270101000081-add-tier-plans-audit-columns.js rename to apps/api/database/migrations/20270101000081-add-tier-plans-audit-columns.js diff --git a/database/migrations/20270101000082-add-tier-categories-special.js b/apps/api/database/migrations/20270101000082-add-tier-categories-special.js similarity index 100% rename from database/migrations/20270101000082-add-tier-categories-special.js rename to apps/api/database/migrations/20270101000082-add-tier-categories-special.js diff --git a/database/migrations/20270101000083-add-categories-audit-columns.js b/apps/api/database/migrations/20270101000083-add-categories-audit-columns.js similarity index 100% rename from database/migrations/20270101000083-add-categories-audit-columns.js rename to apps/api/database/migrations/20270101000083-add-categories-audit-columns.js diff --git a/database/migrations/20270101000084-add-image-asset-id-to-notifications.js b/apps/api/database/migrations/20270101000084-add-image-asset-id-to-notifications.js similarity index 100% rename from database/migrations/20270101000084-add-image-asset-id-to-notifications.js rename to apps/api/database/migrations/20270101000084-add-image-asset-id-to-notifications.js diff --git a/database/migrations/20270101000085-convert-advertisements-badge-label-to-array.js b/apps/api/database/migrations/20270101000085-convert-advertisements-badge-label-to-array.js similarity index 100% rename from database/migrations/20270101000085-convert-advertisements-badge-label-to-array.js rename to apps/api/database/migrations/20270101000085-convert-advertisements-badge-label-to-array.js diff --git a/database/migrations/20270101000086-remove-message-from-notification-broadcasts.js b/apps/api/database/migrations/20270101000086-remove-message-from-notification-broadcasts.js similarity index 100% rename from database/migrations/20270101000086-remove-message-from-notification-broadcasts.js rename to apps/api/database/migrations/20270101000086-remove-message-from-notification-broadcasts.js diff --git a/database/migrations/20270101000087-add-message-back-to-notification-broadcasts.js b/apps/api/database/migrations/20270101000087-add-message-back-to-notification-broadcasts.js similarity index 100% rename from database/migrations/20270101000087-add-message-back-to-notification-broadcasts.js rename to apps/api/database/migrations/20270101000087-add-message-back-to-notification-broadcasts.js diff --git a/database/migrations/20270101000088-relax-plan-bundle-item-uniqueness.js b/apps/api/database/migrations/20270101000088-relax-plan-bundle-item-uniqueness.js similarity index 100% rename from database/migrations/20270101000088-relax-plan-bundle-item-uniqueness.js rename to apps/api/database/migrations/20270101000088-relax-plan-bundle-item-uniqueness.js diff --git a/database/migrations/20270101000089-create-user-tier-grants.js b/apps/api/database/migrations/20270101000089-create-user-tier-grants.js similarity index 100% rename from database/migrations/20270101000089-create-user-tier-grants.js rename to apps/api/database/migrations/20270101000089-create-user-tier-grants.js diff --git a/database/migrations/20270101000090-relax-user-tiers-active-per-plan.js b/apps/api/database/migrations/20270101000090-relax-user-tiers-active-per-plan.js similarity index 100% rename from database/migrations/20270101000090-relax-user-tiers-active-per-plan.js rename to apps/api/database/migrations/20270101000090-relax-user-tiers-active-per-plan.js diff --git a/database/migrations/20270101000091-drop-plan-policies.js b/apps/api/database/migrations/20270101000091-drop-plan-policies.js similarity index 100% rename from database/migrations/20270101000091-drop-plan-policies.js rename to apps/api/database/migrations/20270101000091-drop-plan-policies.js diff --git a/database/migrations/20270101000092-add-tier-plans-status.js b/apps/api/database/migrations/20270101000092-add-tier-plans-status.js similarity index 100% rename from database/migrations/20270101000092-add-tier-plans-status.js rename to apps/api/database/migrations/20270101000092-add-tier-plans-status.js diff --git a/database/migrations/20270101000093-add-tier-plans-is-recommended.js b/apps/api/database/migrations/20270101000093-add-tier-plans-is-recommended.js similarity index 100% rename from database/migrations/20270101000093-add-tier-plans-is-recommended.js rename to apps/api/database/migrations/20270101000093-add-tier-plans-is-recommended.js diff --git a/docker-entrypoint.sh b/apps/api/docker-entrypoint.sh similarity index 100% rename from docker-entrypoint.sh rename to apps/api/docker-entrypoint.sh diff --git a/middleware/auth.middleware.js b/apps/api/middleware/auth.middleware.js similarity index 100% rename from middleware/auth.middleware.js rename to apps/api/middleware/auth.middleware.js diff --git a/middleware/avatar_upload.middleware.js b/apps/api/middleware/avatar_upload.middleware.js similarity index 100% rename from middleware/avatar_upload.middleware.js rename to apps/api/middleware/avatar_upload.middleware.js diff --git a/middleware/badge_upload.middleware.js b/apps/api/middleware/badge_upload.middleware.js similarity index 100% rename from middleware/badge_upload.middleware.js rename to apps/api/middleware/badge_upload.middleware.js diff --git a/middleware/csrf.middleware.js b/apps/api/middleware/csrf.middleware.js similarity index 100% rename from middleware/csrf.middleware.js rename to apps/api/middleware/csrf.middleware.js diff --git a/middleware/mediaGuard.middleware.js b/apps/api/middleware/mediaGuard.middleware.js similarity index 100% rename from middleware/mediaGuard.middleware.js rename to apps/api/middleware/mediaGuard.middleware.js diff --git a/middleware/originGuard.middleware.js b/apps/api/middleware/originGuard.middleware.js similarity index 100% rename from middleware/originGuard.middleware.js rename to apps/api/middleware/originGuard.middleware.js diff --git a/middleware/rateLimiter.middleware.js b/apps/api/middleware/rateLimiter.middleware.js similarity index 100% rename from middleware/rateLimiter.middleware.js rename to apps/api/middleware/rateLimiter.middleware.js diff --git a/middleware/rbac.middleware.js b/apps/api/middleware/rbac.middleware.js similarity index 100% rename from middleware/rbac.middleware.js rename to apps/api/middleware/rbac.middleware.js diff --git a/middleware/task_upload.middleware.js b/apps/api/middleware/task_upload.middleware.js similarity index 100% rename from middleware/task_upload.middleware.js rename to apps/api/middleware/task_upload.middleware.js diff --git a/middleware/validate.middleware.js b/apps/api/middleware/validate.middleware.js similarity index 100% rename from middleware/validate.middleware.js rename to apps/api/middleware/validate.middleware.js diff --git a/models/advertisements/advertisements.attributes.js b/apps/api/models/advertisements/advertisements.attributes.js similarity index 100% rename from models/advertisements/advertisements.attributes.js rename to apps/api/models/advertisements/advertisements.attributes.js diff --git a/models/advertisements/advertisements.mdl.js b/apps/api/models/advertisements/advertisements.mdl.js similarity index 100% rename from models/advertisements/advertisements.mdl.js rename to apps/api/models/advertisements/advertisements.mdl.js diff --git a/models/advertisements/advertisements.placements.js b/apps/api/models/advertisements/advertisements.placements.js similarity index 100% rename from models/advertisements/advertisements.placements.js rename to apps/api/models/advertisements/advertisements.placements.js diff --git a/models/assets/assets.attributes.js b/apps/api/models/assets/assets.attributes.js similarity index 100% rename from models/assets/assets.attributes.js rename to apps/api/models/assets/assets.attributes.js diff --git a/models/assets/assets.mdl.js b/apps/api/models/assets/assets.mdl.js similarity index 100% rename from models/assets/assets.mdl.js rename to apps/api/models/assets/assets.mdl.js diff --git a/models/courses/assessment_session.mdl.js b/apps/api/models/courses/assessment_session.mdl.js similarity index 100% rename from models/courses/assessment_session.mdl.js rename to apps/api/models/courses/assessment_session.mdl.js diff --git a/models/courses/categories.attributes.js b/apps/api/models/courses/categories.attributes.js similarity index 100% rename from models/courses/categories.attributes.js rename to apps/api/models/courses/categories.attributes.js diff --git a/models/courses/categories.mdl.js b/apps/api/models/courses/categories.mdl.js similarity index 100% rename from models/courses/categories.mdl.js rename to apps/api/models/courses/categories.mdl.js diff --git a/models/courses/certificate.mdl.js b/apps/api/models/courses/certificate.mdl.js similarity index 100% rename from models/courses/certificate.mdl.js rename to apps/api/models/courses/certificate.mdl.js diff --git a/models/courses/completion_requirement.mdl.js b/apps/api/models/courses/completion_requirement.mdl.js similarity index 100% rename from models/courses/completion_requirement.mdl.js rename to apps/api/models/courses/completion_requirement.mdl.js diff --git a/models/courses/completion_requirement_progress.mdl.js b/apps/api/models/courses/completion_requirement_progress.mdl.js similarity index 100% rename from models/courses/completion_requirement_progress.mdl.js rename to apps/api/models/courses/completion_requirement_progress.mdl.js diff --git a/models/courses/course_achievement.mdl.js b/apps/api/models/courses/course_achievement.mdl.js similarity index 100% rename from models/courses/course_achievement.mdl.js rename to apps/api/models/courses/course_achievement.mdl.js diff --git a/models/courses/course_assessment.mdl.js b/apps/api/models/courses/course_assessment.mdl.js similarity index 100% rename from models/courses/course_assessment.mdl.js rename to apps/api/models/courses/course_assessment.mdl.js diff --git a/models/courses/course_instructor.mdl.js b/apps/api/models/courses/course_instructor.mdl.js similarity index 100% rename from models/courses/course_instructor.mdl.js rename to apps/api/models/courses/course_instructor.mdl.js diff --git a/models/courses/course_objective.mdl.js b/apps/api/models/courses/course_objective.mdl.js similarity index 100% rename from models/courses/course_objective.mdl.js rename to apps/api/models/courses/course_objective.mdl.js diff --git a/models/courses/course_prerequisite.mdl.js b/apps/api/models/courses/course_prerequisite.mdl.js similarity index 100% rename from models/courses/course_prerequisite.mdl.js rename to apps/api/models/courses/course_prerequisite.mdl.js diff --git a/models/courses/course_purchases.mdl.js b/apps/api/models/courses/course_purchases.mdl.js similarity index 100% rename from models/courses/course_purchases.mdl.js rename to apps/api/models/courses/course_purchases.mdl.js diff --git a/models/courses/course_reading_progress.mdl.js b/apps/api/models/courses/course_reading_progress.mdl.js similarity index 100% rename from models/courses/course_reading_progress.mdl.js rename to apps/api/models/courses/course_reading_progress.mdl.js diff --git a/models/courses/course_role.mdl.js b/apps/api/models/courses/course_role.mdl.js similarity index 100% rename from models/courses/course_role.mdl.js rename to apps/api/models/courses/course_role.mdl.js diff --git a/models/courses/course_units.mdl.js b/apps/api/models/courses/course_units.mdl.js similarity index 100% rename from models/courses/course_units.mdl.js rename to apps/api/models/courses/course_units.mdl.js diff --git a/models/courses/courses.associations.js b/apps/api/models/courses/courses.associations.js similarity index 100% rename from models/courses/courses.associations.js rename to apps/api/models/courses/courses.associations.js diff --git a/models/courses/courses.attributes.js b/apps/api/models/courses/courses.attributes.js similarity index 100% rename from models/courses/courses.attributes.js rename to apps/api/models/courses/courses.attributes.js diff --git a/models/courses/courses.mdl.js b/apps/api/models/courses/courses.mdl.js similarity index 100% rename from models/courses/courses.mdl.js rename to apps/api/models/courses/courses.mdl.js diff --git a/models/courses/lesson_objective.mdl.js b/apps/api/models/courses/lesson_objective.mdl.js similarity index 100% rename from models/courses/lesson_objective.mdl.js rename to apps/api/models/courses/lesson_objective.mdl.js diff --git a/models/courses/lesson_page.mdl.js b/apps/api/models/courses/lesson_page.mdl.js similarity index 100% rename from models/courses/lesson_page.mdl.js rename to apps/api/models/courses/lesson_page.mdl.js diff --git a/models/courses/lesson_reading_progress.mdl.js b/apps/api/models/courses/lesson_reading_progress.mdl.js similarity index 100% rename from models/courses/lesson_reading_progress.mdl.js rename to apps/api/models/courses/lesson_reading_progress.mdl.js diff --git a/models/courses/lessons.mdl.js b/apps/api/models/courses/lessons.mdl.js similarity index 100% rename from models/courses/lessons.mdl.js rename to apps/api/models/courses/lessons.mdl.js diff --git a/models/courses/media_playback_position.mdl.js b/apps/api/models/courses/media_playback_position.mdl.js similarity index 100% rename from models/courses/media_playback_position.mdl.js rename to apps/api/models/courses/media_playback_position.mdl.js diff --git a/models/courses/pending_certificate.mdl.js b/apps/api/models/courses/pending_certificate.mdl.js similarity index 100% rename from models/courses/pending_certificate.mdl.js rename to apps/api/models/courses/pending_certificate.mdl.js diff --git a/models/courses/products.mdl.js b/apps/api/models/courses/products.mdl.js similarity index 100% rename from models/courses/products.mdl.js rename to apps/api/models/courses/products.mdl.js diff --git a/models/courses/quiz_attempt.mdl.js b/apps/api/models/courses/quiz_attempt.mdl.js similarity index 100% rename from models/courses/quiz_attempt.mdl.js rename to apps/api/models/courses/quiz_attempt.mdl.js diff --git a/models/courses/quiz_option.mdl.js b/apps/api/models/courses/quiz_option.mdl.js similarity index 100% rename from models/courses/quiz_option.mdl.js rename to apps/api/models/courses/quiz_option.mdl.js diff --git a/models/courses/quiz_question.mdl.js b/apps/api/models/courses/quiz_question.mdl.js similarity index 100% rename from models/courses/quiz_question.mdl.js rename to apps/api/models/courses/quiz_question.mdl.js diff --git a/models/courses/quiz_session.mdl.js b/apps/api/models/courses/quiz_session.mdl.js similarity index 100% rename from models/courses/quiz_session.mdl.js rename to apps/api/models/courses/quiz_session.mdl.js diff --git a/models/courses/unit_lessons.mdl.js b/apps/api/models/courses/unit_lessons.mdl.js similarity index 100% rename from models/courses/unit_lessons.mdl.js rename to apps/api/models/courses/unit_lessons.mdl.js diff --git a/models/courses/unit_quiz.mdl.js b/apps/api/models/courses/unit_quiz.mdl.js similarity index 100% rename from models/courses/unit_quiz.mdl.js rename to apps/api/models/courses/unit_quiz.mdl.js diff --git a/models/courses/unit_reading_progress.mdl.js b/apps/api/models/courses/unit_reading_progress.mdl.js similarity index 100% rename from models/courses/unit_reading_progress.mdl.js rename to apps/api/models/courses/unit_reading_progress.mdl.js diff --git a/models/courses/units.mdl.js b/apps/api/models/courses/units.mdl.js similarity index 100% rename from models/courses/units.mdl.js rename to apps/api/models/courses/units.mdl.js diff --git a/models/notifications/admin_notification.mdl.js b/apps/api/models/notifications/admin_notification.mdl.js similarity index 100% rename from models/notifications/admin_notification.mdl.js rename to apps/api/models/notifications/admin_notification.mdl.js diff --git a/models/notifications/cron_notification_setting.mdl.js b/apps/api/models/notifications/cron_notification_setting.mdl.js similarity index 100% rename from models/notifications/cron_notification_setting.mdl.js rename to apps/api/models/notifications/cron_notification_setting.mdl.js diff --git a/models/notifications/notification_broadcast.attributes.js b/apps/api/models/notifications/notification_broadcast.attributes.js similarity index 100% rename from models/notifications/notification_broadcast.attributes.js rename to apps/api/models/notifications/notification_broadcast.attributes.js diff --git a/models/notifications/notification_broadcast.mdl.js b/apps/api/models/notifications/notification_broadcast.mdl.js similarity index 100% rename from models/notifications/notification_broadcast.mdl.js rename to apps/api/models/notifications/notification_broadcast.mdl.js diff --git a/models/notifications/user_notification.mdl.js b/apps/api/models/notifications/user_notification.mdl.js similarity index 100% rename from models/notifications/user_notification.mdl.js rename to apps/api/models/notifications/user_notification.mdl.js diff --git a/models/system_badges/system_badges.mdl.js b/apps/api/models/system_badges/system_badges.mdl.js similarity index 100% rename from models/system_badges/system_badges.mdl.js rename to apps/api/models/system_badges/system_badges.mdl.js diff --git a/models/task/task.attributes.js b/apps/api/models/task/task.attributes.js similarity index 100% rename from models/task/task.attributes.js rename to apps/api/models/task/task.attributes.js diff --git a/models/task/task.mdl.js b/apps/api/models/task/task.mdl.js similarity index 100% rename from models/task/task.mdl.js rename to apps/api/models/task/task.mdl.js diff --git a/models/task/task_completion.attributes.js b/apps/api/models/task/task_completion.attributes.js similarity index 100% rename from models/task/task_completion.attributes.js rename to apps/api/models/task/task_completion.attributes.js diff --git a/models/task/task_completion.mdl.js b/apps/api/models/task/task_completion.mdl.js similarity index 100% rename from models/task/task_completion.mdl.js rename to apps/api/models/task/task_completion.mdl.js diff --git a/models/task/task_progress.mdl.js b/apps/api/models/task/task_progress.mdl.js similarity index 100% rename from models/task/task_progress.mdl.js rename to apps/api/models/task/task_progress.mdl.js diff --git a/models/tiers/payment_policies.mdl.js b/apps/api/models/tiers/payment_policies.mdl.js similarity index 100% rename from models/tiers/payment_policies.mdl.js rename to apps/api/models/tiers/payment_policies.mdl.js diff --git a/models/tiers/payments.attributes.js b/apps/api/models/tiers/payments.attributes.js similarity index 100% rename from models/tiers/payments.attributes.js rename to apps/api/models/tiers/payments.attributes.js diff --git a/models/tiers/payments.mdl.js b/apps/api/models/tiers/payments.mdl.js similarity index 100% rename from models/tiers/payments.mdl.js rename to apps/api/models/tiers/payments.mdl.js diff --git a/models/tiers/plan_courses.mdl.js b/apps/api/models/tiers/plan_courses.mdl.js similarity index 100% rename from models/tiers/plan_courses.mdl.js rename to apps/api/models/tiers/plan_courses.mdl.js diff --git a/models/tiers/plan_lessons.mdl.js b/apps/api/models/tiers/plan_lessons.mdl.js similarity index 100% rename from models/tiers/plan_lessons.mdl.js rename to apps/api/models/tiers/plan_lessons.mdl.js diff --git a/models/tiers/plan_units.mdl.js b/apps/api/models/tiers/plan_units.mdl.js similarity index 100% rename from models/tiers/plan_units.mdl.js rename to apps/api/models/tiers/plan_units.mdl.js diff --git a/models/tiers/tier.associations.js b/apps/api/models/tiers/tier.associations.js similarity index 100% rename from models/tiers/tier.associations.js rename to apps/api/models/tiers/tier.associations.js diff --git a/models/tiers/tier_categories.mdl.js b/apps/api/models/tiers/tier_categories.mdl.js similarity index 100% rename from models/tiers/tier_categories.mdl.js rename to apps/api/models/tiers/tier_categories.mdl.js diff --git a/models/tiers/tier_plans.attributes.js b/apps/api/models/tiers/tier_plans.attributes.js similarity index 100% rename from models/tiers/tier_plans.attributes.js rename to apps/api/models/tiers/tier_plans.attributes.js diff --git a/models/tiers/tier_plans.mdl.js b/apps/api/models/tiers/tier_plans.mdl.js similarity index 100% rename from models/tiers/tier_plans.mdl.js rename to apps/api/models/tiers/tier_plans.mdl.js diff --git a/models/tiers/user_tier_grants.mdl.js b/apps/api/models/tiers/user_tier_grants.mdl.js similarity index 100% rename from models/tiers/user_tier_grants.mdl.js rename to apps/api/models/tiers/user_tier_grants.mdl.js diff --git a/models/tiers/user_tiers.mdl.js b/apps/api/models/tiers/user_tiers.mdl.js similarity index 100% rename from models/tiers/user_tiers.mdl.js rename to apps/api/models/tiers/user_tiers.mdl.js diff --git a/models/users/achievement_definitions.mdl.js b/apps/api/models/users/achievement_definitions.mdl.js similarity index 100% rename from models/users/achievement_definitions.mdl.js rename to apps/api/models/users/achievement_definitions.mdl.js diff --git a/models/users/achievements.mdl.js b/apps/api/models/users/achievements.mdl.js similarity index 100% rename from models/users/achievements.mdl.js rename to apps/api/models/users/achievements.mdl.js diff --git a/models/users/trusted_devices.mdl.js b/apps/api/models/users/trusted_devices.mdl.js similarity index 100% rename from models/users/trusted_devices.mdl.js rename to apps/api/models/users/trusted_devices.mdl.js diff --git a/models/users/user_activity.mdl.js b/apps/api/models/users/user_activity.mdl.js similarity index 100% rename from models/users/user_activity.mdl.js rename to apps/api/models/users/user_activity.mdl.js diff --git a/models/users/user_bans.mdl.js b/apps/api/models/users/user_bans.mdl.js similarity index 100% rename from models/users/user_bans.mdl.js rename to apps/api/models/users/user_bans.mdl.js diff --git a/models/users/user_groups.attributes.js b/apps/api/models/users/user_groups.attributes.js similarity index 100% rename from models/users/user_groups.attributes.js rename to apps/api/models/users/user_groups.attributes.js diff --git a/models/users/user_groups.mdl.js b/apps/api/models/users/user_groups.mdl.js similarity index 100% rename from models/users/user_groups.mdl.js rename to apps/api/models/users/user_groups.mdl.js diff --git a/models/users/user_sessions.mdl.js b/apps/api/models/users/user_sessions.mdl.js similarity index 100% rename from models/users/user_sessions.mdl.js rename to apps/api/models/users/user_sessions.mdl.js diff --git a/models/users/users.attributes.js b/apps/api/models/users/users.attributes.js similarity index 100% rename from models/users/users.attributes.js rename to apps/api/models/users/users.attributes.js diff --git a/models/users/users.mdl.js b/apps/api/models/users/users.mdl.js similarity index 100% rename from models/users/users.mdl.js rename to apps/api/models/users/users.mdl.js diff --git a/apps/api/package.json b/apps/api/package.json new file mode 100644 index 0000000..dec0b8a --- /dev/null +++ b/apps/api/package.json @@ -0,0 +1,63 @@ +{ + "name": "api", + "version": "1.0.0", + "description": "STAR Phase 1 - Tier 1 Auth System with CSRF, Rate Limiting, RBAC, Google & System Auth", + "main": "server.js", + "scripts": { + "start": "node server.js", + "dev": "nodemon server.js", + "test": "jest", + "db:migrate": "sequelize-cli db:migrate", + "db:migrate:undo": "sequelize-cli db:migrate:undo", + "db:migrate:undo:all": "sequelize-cli db:migrate:undo:all", + "db:migrate:status": "sequelize-cli db:migrate:status", + "db:seed": "sequelize-cli db:seed:all", + "db:seed:undo": "sequelize-cli db:seed:undo:all" + }, + "dependencies": { + "@aws-sdk/client-s3": "^3.1068.0", + "@aws-sdk/lib-storage": "^3.1085.0", + "@aws-sdk/s3-request-presigner": "^3.1068.0", + "axios": "^1.16.0", + "bcryptjs": "^2.4.3", + "connect-pg-simple": "^10.0.0", + "cookie-parser": "^1.4.6", + "cors": "^2.8.5", + "csurf": "^1.11.0", + "currency-codes": "^2.2.0", + "dotenv": "^16.0.3", + "express": "^4.18.2", + "express-rate-limit": "^6.10.0", + "express-session": "^1.17.3", + "express-validator": "^7.0.1", + "ffprobe-static": "^3.1.0", + "fluent-ffmpeg": "^2.1.3", + "form-data": "^4.0.5", + "google-auth-library": "^9.0.0", + "http-proxy-middleware": "^4.0.0", + "jsonwebtoken": "^9.0.1", + "multer": "^2.1.1", + "node-cron": "^4.2.1", + "nodemailer": "^6.9.5", + "path": "^0.12.7", + "pg": "^8.11.3", + "pg-hstore": "^2.3.4", + "rate-limit-redis": "^4.0.0", + "redis": "^4.6.7", + "sequelize": "^6.32.1", + "sharp": "^0.35.3", + "ua-parser-js": "^2.0.10", + "uuid": "^9.0.0" + }, + "devDependencies": { + "jest": "^30.4.2", + "nodemon": "^3.0.1", + "sequelize-cli": "^6.6.5" + }, + "jest": { + "testMatch": [ + "**/tests/**/*.test.js" + ], + "forceExit": true + } +} diff --git a/providers/paypal.provider.js b/apps/api/providers/paypal.provider.js similarity index 100% rename from providers/paypal.provider.js rename to apps/api/providers/paypal.provider.js diff --git a/providers/registry.js b/apps/api/providers/registry.js similarity index 100% rename from providers/registry.js rename to apps/api/providers/registry.js diff --git a/routes/admin/achievements.routes.js b/apps/api/routes/admin/achievements.routes.js similarity index 100% rename from routes/admin/achievements.routes.js rename to apps/api/routes/admin/achievements.routes.js diff --git a/routes/admin/admin.routes.js b/apps/api/routes/admin/admin.routes.js similarity index 100% rename from routes/admin/admin.routes.js rename to apps/api/routes/admin/admin.routes.js diff --git a/routes/admin/advertisements.routes.js b/apps/api/routes/admin/advertisements.routes.js similarity index 100% rename from routes/admin/advertisements.routes.js rename to apps/api/routes/admin/advertisements.routes.js diff --git a/routes/admin/assets.routes.js b/apps/api/routes/admin/assets.routes.js similarity index 100% rename from routes/admin/assets.routes.js rename to apps/api/routes/admin/assets.routes.js diff --git a/routes/admin/categories.routes.js b/apps/api/routes/admin/categories.routes.js similarity index 100% rename from routes/admin/categories.routes.js rename to apps/api/routes/admin/categories.routes.js diff --git a/routes/admin/courses.routes.js b/apps/api/routes/admin/courses.routes.js similarity index 100% rename from routes/admin/courses.routes.js rename to apps/api/routes/admin/courses.routes.js diff --git a/routes/admin/dashboard.routes.js b/apps/api/routes/admin/dashboard.routes.js similarity index 100% rename from routes/admin/dashboard.routes.js rename to apps/api/routes/admin/dashboard.routes.js diff --git a/routes/admin/groups.routes.js b/apps/api/routes/admin/groups.routes.js similarity index 100% rename from routes/admin/groups.routes.js rename to apps/api/routes/admin/groups.routes.js diff --git a/routes/admin/lessons.routes.js b/apps/api/routes/admin/lessons.routes.js similarity index 100% rename from routes/admin/lessons.routes.js rename to apps/api/routes/admin/lessons.routes.js diff --git a/routes/admin/media.routes.js b/apps/api/routes/admin/media.routes.js similarity index 100% rename from routes/admin/media.routes.js rename to apps/api/routes/admin/media.routes.js diff --git a/routes/admin/notificationBroadcasts.routes.js b/apps/api/routes/admin/notificationBroadcasts.routes.js similarity index 100% rename from routes/admin/notificationBroadcasts.routes.js rename to apps/api/routes/admin/notificationBroadcasts.routes.js diff --git a/routes/admin/notificationSettings.routes.js b/apps/api/routes/admin/notificationSettings.routes.js similarity index 100% rename from routes/admin/notificationSettings.routes.js rename to apps/api/routes/admin/notificationSettings.routes.js diff --git a/routes/admin/notifications.routes.js b/apps/api/routes/admin/notifications.routes.js similarity index 100% rename from routes/admin/notifications.routes.js rename to apps/api/routes/admin/notifications.routes.js diff --git a/routes/admin/products.routes.js b/apps/api/routes/admin/products.routes.js similarity index 100% rename from routes/admin/products.routes.js rename to apps/api/routes/admin/products.routes.js diff --git a/routes/admin/profile.routes.js b/apps/api/routes/admin/profile.routes.js similarity index 100% rename from routes/admin/profile.routes.js rename to apps/api/routes/admin/profile.routes.js diff --git a/routes/admin/task.routes.js b/apps/api/routes/admin/task.routes.js similarity index 100% rename from routes/admin/task.routes.js rename to apps/api/routes/admin/task.routes.js diff --git a/routes/admin/tier_categories.routes.js b/apps/api/routes/admin/tier_categories.routes.js similarity index 100% rename from routes/admin/tier_categories.routes.js rename to apps/api/routes/admin/tier_categories.routes.js diff --git a/routes/admin/tier_policies.routes.js b/apps/api/routes/admin/tier_policies.routes.js similarity index 100% rename from routes/admin/tier_policies.routes.js rename to apps/api/routes/admin/tier_policies.routes.js diff --git a/routes/admin/tiers.routes.js b/apps/api/routes/admin/tiers.routes.js similarity index 100% rename from routes/admin/tiers.routes.js rename to apps/api/routes/admin/tiers.routes.js diff --git a/routes/admin/units.routes.js b/apps/api/routes/admin/units.routes.js similarity index 100% rename from routes/admin/units.routes.js rename to apps/api/routes/admin/units.routes.js diff --git a/routes/admin/users.routes.js b/apps/api/routes/admin/users.routes.js similarity index 100% rename from routes/admin/users.routes.js rename to apps/api/routes/admin/users.routes.js diff --git a/routes/auth.routes.js b/apps/api/routes/auth.routes.js similarity index 100% rename from routes/auth.routes.js rename to apps/api/routes/auth.routes.js diff --git a/routes/client/advertisements.routes.js b/apps/api/routes/client/advertisements.routes.js similarity index 100% rename from routes/client/advertisements.routes.js rename to apps/api/routes/client/advertisements.routes.js diff --git a/routes/client/client.routes.js b/apps/api/routes/client/client.routes.js similarity index 100% rename from routes/client/client.routes.js rename to apps/api/routes/client/client.routes.js diff --git a/routes/client/course_purchases.routes.js b/apps/api/routes/client/course_purchases.routes.js similarity index 100% rename from routes/client/course_purchases.routes.js rename to apps/api/routes/client/course_purchases.routes.js diff --git a/routes/client/courses.routes.js b/apps/api/routes/client/courses.routes.js similarity index 100% rename from routes/client/courses.routes.js rename to apps/api/routes/client/courses.routes.js diff --git a/routes/client/groups.routes.js b/apps/api/routes/client/groups.routes.js similarity index 100% rename from routes/client/groups.routes.js rename to apps/api/routes/client/groups.routes.js diff --git a/routes/client/lessons.routes.js b/apps/api/routes/client/lessons.routes.js similarity index 100% rename from routes/client/lessons.routes.js rename to apps/api/routes/client/lessons.routes.js diff --git a/routes/client/media.routes.js b/apps/api/routes/client/media.routes.js similarity index 100% rename from routes/client/media.routes.js rename to apps/api/routes/client/media.routes.js diff --git a/routes/client/notifications.routes.js b/apps/api/routes/client/notifications.routes.js similarity index 100% rename from routes/client/notifications.routes.js rename to apps/api/routes/client/notifications.routes.js diff --git a/routes/client/tiers.routes.js b/apps/api/routes/client/tiers.routes.js similarity index 100% rename from routes/client/tiers.routes.js rename to apps/api/routes/client/tiers.routes.js diff --git a/routes/client/units.routes.js b/apps/api/routes/client/units.routes.js similarity index 100% rename from routes/client/units.routes.js rename to apps/api/routes/client/units.routes.js diff --git a/routes/health.routes.js b/apps/api/routes/health.routes.js similarity index 100% rename from routes/health.routes.js rename to apps/api/routes/health.routes.js diff --git a/routes/public/media.routes.js b/apps/api/routes/public/media.routes.js similarity index 100% rename from routes/public/media.routes.js rename to apps/api/routes/public/media.routes.js diff --git a/routes/public/public.routes.js b/apps/api/routes/public/public.routes.js similarity index 100% rename from routes/public/public.routes.js rename to apps/api/routes/public/public.routes.js diff --git a/routes/staff/staff.routes.js b/apps/api/routes/staff/staff.routes.js similarity index 100% rename from routes/staff/staff.routes.js rename to apps/api/routes/staff/staff.routes.js diff --git a/scripts/backfill-durations.js b/apps/api/scripts/backfill-durations.js similarity index 100% rename from scripts/backfill-durations.js rename to apps/api/scripts/backfill-durations.js diff --git a/scripts/garage-init.sh b/apps/api/scripts/garage-init.sh similarity index 100% rename from scripts/garage-init.sh rename to apps/api/scripts/garage-init.sh diff --git a/scripts/get_gmail_refresh_token.js b/apps/api/scripts/get_gmail_refresh_token.js similarity index 100% rename from scripts/get_gmail_refresh_token.js rename to apps/api/scripts/get_gmail_refresh_token.js diff --git a/server.js b/apps/api/server.js similarity index 100% rename from server.js rename to apps/api/server.js diff --git a/services/accountStatus.service.js b/apps/api/services/accountStatus.service.js similarity index 100% rename from services/accountStatus.service.js rename to apps/api/services/accountStatus.service.js diff --git a/services/achievements.service.js b/apps/api/services/achievements.service.js similarity index 100% rename from services/achievements.service.js rename to apps/api/services/achievements.service.js diff --git a/services/assetTranscode.service.js b/apps/api/services/assetTranscode.service.js similarity index 100% rename from services/assetTranscode.service.js rename to apps/api/services/assetTranscode.service.js diff --git a/services/avatar.service.js b/apps/api/services/avatar.service.js similarity index 100% rename from services/avatar.service.js rename to apps/api/services/avatar.service.js diff --git a/services/certificate-record.service.js b/apps/api/services/certificate-record.service.js similarity index 100% rename from services/certificate-record.service.js rename to apps/api/services/certificate-record.service.js diff --git a/services/certificate.service.js b/apps/api/services/certificate.service.js similarity index 100% rename from services/certificate.service.js rename to apps/api/services/certificate.service.js diff --git a/services/chibisafe.service.js b/apps/api/services/chibisafe.service.js similarity index 100% rename from services/chibisafe.service.js rename to apps/api/services/chibisafe.service.js diff --git a/services/completion_requirements.service.js b/apps/api/services/completion_requirements.service.js similarity index 100% rename from services/completion_requirements.service.js rename to apps/api/services/completion_requirements.service.js diff --git a/services/course_reading_progress.service.js b/apps/api/services/course_reading_progress.service.js similarity index 100% rename from services/course_reading_progress.service.js rename to apps/api/services/course_reading_progress.service.js diff --git a/services/email.service.js b/apps/api/services/email.service.js similarity index 100% rename from services/email.service.js rename to apps/api/services/email.service.js diff --git a/services/ffmpeg.service.js b/apps/api/services/ffmpeg.service.js similarity index 100% rename from services/ffmpeg.service.js rename to apps/api/services/ffmpeg.service.js diff --git a/services/ffprobe.service.js b/apps/api/services/ffprobe.service.js similarity index 100% rename from services/ffprobe.service.js rename to apps/api/services/ffprobe.service.js diff --git a/services/health.service.js b/apps/api/services/health.service.js similarity index 100% rename from services/health.service.js rename to apps/api/services/health.service.js diff --git a/services/mediaToken.service.js b/apps/api/services/mediaToken.service.js similarity index 100% rename from services/mediaToken.service.js rename to apps/api/services/mediaToken.service.js diff --git a/services/payment.service.js b/apps/api/services/payment.service.js similarity index 100% rename from services/payment.service.js rename to apps/api/services/payment.service.js diff --git a/services/planAccess.service.js b/apps/api/services/planAccess.service.js similarity index 100% rename from services/planAccess.service.js rename to apps/api/services/planAccess.service.js diff --git a/services/playback_position.service.js b/apps/api/services/playback_position.service.js similarity index 100% rename from services/playback_position.service.js rename to apps/api/services/playback_position.service.js diff --git a/services/reading_progress.service.js b/apps/api/services/reading_progress.service.js similarity index 100% rename from services/reading_progress.service.js rename to apps/api/services/reading_progress.service.js diff --git a/services/s3.service.js b/apps/api/services/s3.service.js similarity index 100% rename from services/s3.service.js rename to apps/api/services/s3.service.js diff --git a/services/task_reading_progress_sync.service.js b/apps/api/services/task_reading_progress_sync.service.js similarity index 100% rename from services/task_reading_progress_sync.service.js rename to apps/api/services/task_reading_progress_sync.service.js diff --git a/services/tierGrants.service.js b/apps/api/services/tierGrants.service.js similarity index 100% rename from services/tierGrants.service.js rename to apps/api/services/tierGrants.service.js diff --git a/services/trustedDevice.service.js b/apps/api/services/trustedDevice.service.js similarity index 100% rename from services/trustedDevice.service.js rename to apps/api/services/trustedDevice.service.js diff --git a/templates/certificate.typ b/apps/api/templates/certificate.typ similarity index 100% rename from templates/certificate.typ rename to apps/api/templates/certificate.typ diff --git a/templates/fonts/Arimo/Arimo-Bold.ttf b/apps/api/templates/fonts/Arimo/Arimo-Bold.ttf similarity index 100% rename from templates/fonts/Arimo/Arimo-Bold.ttf rename to apps/api/templates/fonts/Arimo/Arimo-Bold.ttf diff --git a/templates/fonts/Arimo/Arimo-BoldItalic.ttf b/apps/api/templates/fonts/Arimo/Arimo-BoldItalic.ttf similarity index 100% rename from templates/fonts/Arimo/Arimo-BoldItalic.ttf rename to apps/api/templates/fonts/Arimo/Arimo-BoldItalic.ttf diff --git a/templates/fonts/Arimo/Arimo-Italic.ttf b/apps/api/templates/fonts/Arimo/Arimo-Italic.ttf similarity index 100% rename from templates/fonts/Arimo/Arimo-Italic.ttf rename to apps/api/templates/fonts/Arimo/Arimo-Italic.ttf diff --git a/templates/fonts/Arimo/Arimo-Regular.ttf b/apps/api/templates/fonts/Arimo/Arimo-Regular.ttf similarity index 100% rename from templates/fonts/Arimo/Arimo-Regular.ttf rename to apps/api/templates/fonts/Arimo/Arimo-Regular.ttf diff --git a/templates/fonts/Arimo/OFL.txt b/apps/api/templates/fonts/Arimo/OFL.txt similarity index 100% rename from templates/fonts/Arimo/OFL.txt rename to apps/api/templates/fonts/Arimo/OFL.txt diff --git a/templates/philpro-logo.png b/apps/api/templates/philpro-logo.png similarity index 100% rename from templates/philpro-logo.png rename to apps/api/templates/philpro-logo.png diff --git a/templates/signature-placeholder.png b/apps/api/templates/signature-placeholder.png similarity index 100% rename from templates/signature-placeholder.png rename to apps/api/templates/signature-placeholder.png diff --git a/tests/controllers/courses.controller.access.test.js b/apps/api/tests/controllers/courses.controller.access.test.js similarity index 100% rename from tests/controllers/courses.controller.access.test.js rename to apps/api/tests/controllers/courses.controller.access.test.js diff --git a/tests/controllers/tiers.controller.capture.test.js b/apps/api/tests/controllers/tiers.controller.capture.test.js similarity index 100% rename from tests/controllers/tiers.controller.capture.test.js rename to apps/api/tests/controllers/tiers.controller.capture.test.js diff --git a/tests/cron/fail_stale_payments.test.js b/apps/api/tests/cron/fail_stale_payments.test.js similarity index 100% rename from tests/cron/fail_stale_payments.test.js rename to apps/api/tests/cron/fail_stale_payments.test.js diff --git a/tests/middleware/originGuard.test.js b/apps/api/tests/middleware/originGuard.test.js similarity index 100% rename from tests/middleware/originGuard.test.js rename to apps/api/tests/middleware/originGuard.test.js diff --git a/tests/middleware/rateLimiter.test.js b/apps/api/tests/middleware/rateLimiter.test.js similarity index 100% rename from tests/middleware/rateLimiter.test.js rename to apps/api/tests/middleware/rateLimiter.test.js diff --git a/tests/middleware/rbac.test.js b/apps/api/tests/middleware/rbac.test.js similarity index 100% rename from tests/middleware/rbac.test.js rename to apps/api/tests/middleware/rbac.test.js diff --git a/tests/providers/paypal.provider.test.js b/apps/api/tests/providers/paypal.provider.test.js similarity index 100% rename from tests/providers/paypal.provider.test.js rename to apps/api/tests/providers/paypal.provider.test.js diff --git a/tests/providers/registry.test.js b/apps/api/tests/providers/registry.test.js similarity index 100% rename from tests/providers/registry.test.js rename to apps/api/tests/providers/registry.test.js diff --git a/tests/services/health.test.js b/apps/api/tests/services/health.test.js similarity index 100% rename from tests/services/health.test.js rename to apps/api/tests/services/health.test.js diff --git a/tests/services/payment.service.test.js b/apps/api/tests/services/payment.service.test.js similarity index 100% rename from tests/services/payment.service.test.js rename to apps/api/tests/services/payment.service.test.js diff --git a/tests/services/planAccess.service.test.js b/apps/api/tests/services/planAccess.service.test.js similarity index 100% rename from tests/services/planAccess.service.test.js rename to apps/api/tests/services/planAccess.service.test.js diff --git a/tests/utils/datetime.test.js b/apps/api/tests/utils/datetime.test.js similarity index 100% rename from tests/utils/datetime.test.js rename to apps/api/tests/utils/datetime.test.js diff --git a/tests/utils/otp.test.js b/apps/api/tests/utils/otp.test.js similarity index 100% rename from tests/utils/otp.test.js rename to apps/api/tests/utils/otp.test.js diff --git a/tests/utils/response.test.js b/apps/api/tests/utils/response.test.js similarity index 100% rename from tests/utils/response.test.js rename to apps/api/tests/utils/response.test.js diff --git a/tests/utils/token.test.js b/apps/api/tests/utils/token.test.js similarity index 100% rename from tests/utils/token.test.js rename to apps/api/tests/utils/token.test.js diff --git a/utils/audienceResolver.util.js b/apps/api/utils/audienceResolver.util.js similarity index 100% rename from utils/audienceResolver.util.js rename to apps/api/utils/audienceResolver.util.js diff --git a/utils/buildQuery.util.js b/apps/api/utils/buildQuery.util.js similarity index 100% rename from utils/buildQuery.util.js rename to apps/api/utils/buildQuery.util.js diff --git a/utils/courses/archive.util.js b/apps/api/utils/courses/archive.util.js similarity index 100% rename from utils/courses/archive.util.js rename to apps/api/utils/courses/archive.util.js diff --git a/utils/courses/completion_requirements.registry.js b/apps/api/utils/courses/completion_requirements.registry.js similarity index 100% rename from utils/courses/completion_requirements.registry.js rename to apps/api/utils/courses/completion_requirements.registry.js diff --git a/utils/courses/grading.util.js b/apps/api/utils/courses/grading.util.js similarity index 100% rename from utils/courses/grading.util.js rename to apps/api/utils/courses/grading.util.js diff --git a/utils/courses/hierarchy.util.js b/apps/api/utils/courses/hierarchy.util.js similarity index 100% rename from utils/courses/hierarchy.util.js rename to apps/api/utils/courses/hierarchy.util.js diff --git a/utils/courses/junction.util.js b/apps/api/utils/courses/junction.util.js similarity index 100% rename from utils/courses/junction.util.js rename to apps/api/utils/courses/junction.util.js diff --git a/utils/courses/objectives.util.js b/apps/api/utils/courses/objectives.util.js similarity index 100% rename from utils/courses/objectives.util.js rename to apps/api/utils/courses/objectives.util.js diff --git a/utils/courses/permanentDelete.util.js b/apps/api/utils/courses/permanentDelete.util.js similarity index 100% rename from utils/courses/permanentDelete.util.js rename to apps/api/utils/courses/permanentDelete.util.js diff --git a/utils/courses/quiz_security.util.js b/apps/api/utils/courses/quiz_security.util.js similarity index 100% rename from utils/courses/quiz_security.util.js rename to apps/api/utils/courses/quiz_security.util.js diff --git a/utils/courses/resolvePrerequisiteTitles.util.js b/apps/api/utils/courses/resolvePrerequisiteTitles.util.js similarity index 100% rename from utils/courses/resolvePrerequisiteTitles.util.js rename to apps/api/utils/courses/resolvePrerequisiteTitles.util.js diff --git a/utils/courses/restore.util.js b/apps/api/utils/courses/restore.util.js similarity index 100% rename from utils/courses/restore.util.js rename to apps/api/utils/courses/restore.util.js diff --git a/utils/courses/taskPrerequisites.util.js b/apps/api/utils/courses/taskPrerequisites.util.js similarity index 100% rename from utils/courses/taskPrerequisites.util.js rename to apps/api/utils/courses/taskPrerequisites.util.js diff --git a/utils/datetime.util.js b/apps/api/utils/datetime.util.js similarity index 100% rename from utils/datetime.util.js rename to apps/api/utils/datetime.util.js diff --git a/utils/defaultGroup.util.js b/apps/api/utils/defaultGroup.util.js similarity index 100% rename from utils/defaultGroup.util.js rename to apps/api/utils/defaultGroup.util.js diff --git a/utils/duration.util.js b/apps/api/utils/duration.util.js similarity index 100% rename from utils/duration.util.js rename to apps/api/utils/duration.util.js diff --git a/utils/excludeJSONBPaths.util.js b/apps/api/utils/excludeJSONBPaths.util.js similarity index 100% rename from utils/excludeJSONBPaths.util.js rename to apps/api/utils/excludeJSONBPaths.util.js diff --git a/utils/fieldValues.util.js b/apps/api/utils/fieldValues.util.js similarity index 100% rename from utils/fieldValues.util.js rename to apps/api/utils/fieldValues.util.js diff --git a/utils/google_oidc.util.js b/apps/api/utils/google_oidc.util.js similarity index 100% rename from utils/google_oidc.util.js rename to apps/api/utils/google_oidc.util.js diff --git a/utils/logActivity.util.js b/apps/api/utils/logActivity.util.js similarity index 100% rename from utils/logActivity.util.js rename to apps/api/utils/logActivity.util.js diff --git a/utils/modelToAttributes.util.js b/apps/api/utils/modelToAttributes.util.js similarity index 100% rename from utils/modelToAttributes.util.js rename to apps/api/utils/modelToAttributes.util.js diff --git a/utils/notificationVisibility.util.js b/apps/api/utils/notificationVisibility.util.js similarity index 100% rename from utils/notificationVisibility.util.js rename to apps/api/utils/notificationVisibility.util.js diff --git a/utils/otp.util.js b/apps/api/utils/otp.util.js similarity index 100% rename from utils/otp.util.js rename to apps/api/utils/otp.util.js diff --git a/utils/paginate.util.js b/apps/api/utils/paginate.util.js similarity index 100% rename from utils/paginate.util.js rename to apps/api/utils/paginate.util.js diff --git a/utils/personalInfo.util.js b/apps/api/utils/personalInfo.util.js similarity index 100% rename from utils/personalInfo.util.js rename to apps/api/utils/personalInfo.util.js diff --git a/utils/purchasable.util.js b/apps/api/utils/purchasable.util.js similarity index 100% rename from utils/purchasable.util.js rename to apps/api/utils/purchasable.util.js diff --git a/utils/renderTemplate.util.js b/apps/api/utils/renderTemplate.util.js similarity index 100% rename from utils/renderTemplate.util.js rename to apps/api/utils/renderTemplate.util.js diff --git a/utils/resolveAvatar.util.js b/apps/api/utils/resolveAvatar.util.js similarity index 100% rename from utils/resolveAvatar.util.js rename to apps/api/utils/resolveAvatar.util.js diff --git a/utils/response.util.js b/apps/api/utils/response.util.js similarity index 100% rename from utils/response.util.js rename to apps/api/utils/response.util.js diff --git a/utils/session_info.util.js b/apps/api/utils/session_info.util.js similarity index 100% rename from utils/session_info.util.js rename to apps/api/utils/session_info.util.js diff --git a/utils/suspendGuard.util.js b/apps/api/utils/suspendGuard.util.js similarity index 100% rename from utils/suspendGuard.util.js rename to apps/api/utils/suspendGuard.util.js diff --git a/utils/token.util.js b/apps/api/utils/token.util.js similarity index 100% rename from utils/token.util.js rename to apps/api/utils/token.util.js diff --git a/utils/withTransactionRetry.util.js b/apps/api/utils/withTransactionRetry.util.js similarity index 100% rename from utils/withTransactionRetry.util.js rename to apps/api/utils/withTransactionRetry.util.js diff --git a/validators/auth.validator.js b/apps/api/validators/auth.validator.js similarity index 100% rename from validators/auth.validator.js rename to apps/api/validators/auth.validator.js diff --git a/validators/profile.validator.js b/apps/api/validators/profile.validator.js similarity index 100% rename from validators/profile.validator.js rename to apps/api/validators/profile.validator.js diff --git a/apps/web/.dockerignore b/apps/web/.dockerignore new file mode 100644 index 0000000..5d0850b --- /dev/null +++ b/apps/web/.dockerignore @@ -0,0 +1,7 @@ +node_modules +.env +src +public +*.config.js +*.config.ts +index.html diff --git a/apps/web/.env.example b/apps/web/.env.example new file mode 100644 index 0000000..8a9f8af --- /dev/null +++ b/apps/web/.env.example @@ -0,0 +1,38 @@ +# ═══════════════════════════════════════════════════════════════════════════════ +# $APP_NAME — Frontend Environment Variables Template +# Copy to .env and fill in all CHANGE_ME values before building. +# +# Self-hosted setup: +# 1. cp .env.example .env +# 2. Fill in every CHANGE_ME value below +# 3. npm run build (bakes env vars into the dist/ bundle) +# 4. docker build -t $APP_NAME-app . +# (or serve dist/ with any static host — Nginx, Caddy, Vercel, etc.) +# +# NOTE: These are BUILD-TIME variables (VITE_ prefix). Changing them after +# the build has no effect — you must rebuild to pick up new values. +# ═══════════════════════════════════════════════════════════════════════════════ + +# ── API Connection ──────────────────────────────────────────────────────────── +# Point to your backend's public URL — no trailing slash. +# Must match APP_URL / ALLOWED_ORIGINS in the backend .env. +VITE_APP_NAME=starr +VITE_API_URL=https://api.yourdomain.com/api +VITE_APP_URL=https://api.yourdomain.com + +# ── Environment ─────────────────────────────────────────────────────────────── +# "production" (droplet) or "qas" (home-hosted, behind Cloudflare Tunnel). +# Set to "qas" only on the QAS Preview build in Vercel's project settings. +VITE_APP_ENV=production + +# ── PayPal ──────────────────────────────────────────────────────────────────── +# Client ID is the public key — safe to expose in the browser bundle. +# developer.paypal.com → My Apps & Credentials → Live tab → Client ID +VITE_PAYPAL_CLIENT_ID=CHANGE_ME + +# ── Country detection (phone input) ──────────────────────────────────────────── +# IP → country lookup used to pre-select the phone input's dialing code. +# Defaults to the free hosted instance; self-host for production via +# https://github.com/lineofflight/country (Docker, needs a free MaxMind +# license key) and point this at your own instance instead. +VITE_COUNTRY_API_URL=https://api.country.is diff --git a/apps/web/.gitignore b/apps/web/.gitignore new file mode 100644 index 0000000..bcd6d22 --- /dev/null +++ b/apps/web/.gitignore @@ -0,0 +1,49 @@ +# ── Dependencies ────────────────────────────────────────────────────────────── +node_modules/ + +# ── Environment / Secrets ───────────────────────────────────────────────────── +.env +.env.local +.env.*.local +# Keep .env.example — it is safe and documents required variables + +# ── SSL / TLS / Keys ────────────────────────────────────────────────────────── +*.pem +*.key +*.cert +*.crt +*.p12 +*.pfx + +# ── Build / Output ──────────────────────────────────────────────────────────── +dist/ +dist-ssr/ + +# ── Tauri ───────────────────────────────────────────────────────────────────── +src-tauri/target/ +.tauri/ + +# ── Logs ────────────────────────────────────────────────────────────────────── +*.log +logs/ +npm-debug.log* +pnpm-debug.log* +yarn-debug.log* +lerna-debug.log* + +# ── OS ──────────────────────────────────────────────────────────────────────── +.DS_Store +Thumbs.db +desktop.ini + +# ── Editors ─────────────────────────────────────────────────────────────────── +.vscode/* +!.vscode/extensions.json +.idea/ +*.swp +*.swo +*.suo +*.ntvs* +*.njsproj +*.sln +.vercel diff --git a/apps/web/.vscode/extensions.json b/apps/web/.vscode/extensions.json new file mode 100644 index 0000000..e69de29 diff --git a/apps/web/Dockerfile b/apps/web/Dockerfile new file mode 100644 index 0000000..a450ee2 --- /dev/null +++ b/apps/web/Dockerfile @@ -0,0 +1,9 @@ +# Pre-built image — run `npm run build` first so dist/ exists. +FROM nginx:1.27-alpine + +COPY dist/ /usr/share/nginx/html/ +COPY nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/apps/web/README.md b/apps/web/README.md new file mode 100644 index 0000000..92dc71f --- /dev/null +++ b/apps/web/README.md @@ -0,0 +1,177 @@ +# new_starr_app — Frontend + +React + Vite CSR frontend for the STARR LMS platform. + +--- + +## Page Metadata + +Metadata (`
+ {React.string("Annotation")} +
++ {React.string("Annotation")} +
+Loading {APP_NAME}...
++ Preview — this is how it will appear in the carousel. +
++ {description} +
+ )} +clickAction.go(navigate) : undefined} + > + {announcement.title || "Announcement"} +
+ + {/* Only way to dismiss a sticky alert. */} +No {fileType} files found.
+File type
+ {hasActiveFilters && ( + + )} +Unknown block type.
; + } +} + +// ─── Default content per type ───────────────────────────────────────────────── + +export const DEFAULT_CONTENT = { + "text": { body: "" }, + "image": { asset_id: null, url: "", alt: "" }, + "text-image": { body: "", asset_id: null, url: "", alt: "", image_position: "right" }, + "video": { asset_id: null, url: "", thumbnail_url: "", duration_seconds: 0 }, + "text-video": { body: "", asset_id: null, url: "", thumbnail_url: "", video_position: "right", duration_seconds: 0 }, + "audio": { asset_id: null, url: "", title: "", artist: "", tag: "", thumbnail: "", duration_seconds: 0 }, + "code": { language: "javascript", code: "" }, + "markdown": { body: "" }, +}; + +// ─── List ───────────────────────────────────────────────────────────────────── + +export function BlockList({ blocks, onUpdate, onMove, onDelete }) { + if (!blocks.length) { + return ( +No blocks yet.
++ Use the button below to add your first block. +
+{title}
+ {artist &&{artist}
} +Change Image
+
+ +
Nothing to preview yet.
+ )} ++ {hovered.r > 0 && hovered.c > 0 + ? `${hovered.r} × ${hovered.c} table` + : "Hover to select size"} +
+ + {/* Grid */} +. If the cursor is already inside a
+ // element, unwraps it instead.
+
+ const toggleInlineCode = () => {
+ const sel = window.getSelection();
+ if (!sel || sel.rangeCount === 0) return;
+ const range = sel.getRangeAt(0);
+ const ancestor = range.commonAncestorContainer;
+ const codeParent = (ancestor.nodeType === 3 ? ancestor.parentElement : ancestor)?.closest("code");
+
+ if (codeParent) {
+ const text = document.createTextNode(codeParent.textContent ?? "");
+ codeParent.replaceWith(text);
+ onChange(editorRef.current.innerHTML);
+ } else {
+ const text = sel.toString();
+ if (!text) return;
+ exec("insertHTML", `${text}`);
+ onChange(editorRef.current.innerHTML);
+ }
+ };
+
+ // ── Code block insertion ───────────────────────────────────────────────────
+
+ const insertCodeBlock = () => {
+ editorRef.current?.focus();
+ const sel = window.getSelection();
+ const selectedText = sel?.toString() || "// your code here";
+ exec("insertHTML", `${selectedText}
`);
+ onChange(editorRef.current.innerHTML);
+ };
+
+ // ── Table insertion ────────────────────────────────────────────────────────
+ // Builds a with a header row (th) + (rows-1) data rows.
+ // Each cell is contenteditable (inherited from the editor).
+ // A paragraph after the table lets the user continue typing below it.
+
+ const insertTable = (rows, cols) => {
+ if (rows < 1 || cols < 1) return;
+
+ // Save cursor before opening picker collapses it
+ editorRef.current?.focus();
+ const sel = window.getSelection();
+ if (savedRange.current && sel) {
+ sel.removeAllRanges();
+ sel.addRange(savedRange.current);
+ }
+
+ // Build header row
+ const headerCells = Array.from({ length: cols })
+ .map((_, i) => `Column ${i + 1} `)
+ .join("");
+
+ // Build body rows
+ const bodyRows = Array.from({ length: rows - 1 })
+ .map(() =>
+ `${Array.from({ length: cols }).map(() => "
").join("")} `
+ )
+ .join("");
+
+ const tableHTML = `
+
+ ${headerCells}
+ ${bodyRows}
+
+
+ `;
+
+ document.execCommand("insertHTML", false, tableHTML);
+ onChange(editorRef.current.innerHTML);
+ savedRange.current = null;
+ };
+
+ const openTablePicker = () => {
+ // Save current cursor so we can restore it after the picker closes
+ const sel = window.getSelection();
+ if (sel && sel.rangeCount > 0) {
+ savedRange.current = sel.getRangeAt(0).cloneRange();
+ }
+ setTablePickerOpen(true);
+ };
+
+ // ── Toolbar groups ─────────────────────────────────────────────────────────
+
+ const GROUPS = [
+ [
+ { cmd: "bold", Icon: Bold, title: "Bold" },
+ { cmd: "italic", Icon: Italic, title: "Italic" },
+ { cmd: "underline", Icon: Underline, title: "Underline" },
+ ],
+ [
+ { cmd: "justifyLeft", Icon: AlignLeft, title: "Align left" },
+ { cmd: "justifyCenter", Icon: AlignCenter, title: "Align center" },
+ { cmd: "justifyRight", Icon: AlignRight, title: "Align right" },
+ { cmd: "justifyFull", Icon: AlignJustify, title: "Justify" },
+ ],
+ [
+ { cmd: "insertUnorderedList", Icon: List, title: "Bullet list" },
+ { cmd: "insertOrderedList", Icon: ListOrdered, title: "Numbered list" },
+ { cmd: "indent", Icon: Indent, title: "Indent" },
+ { cmd: "outdent", Icon: Outdent, title: "Outdent" },
+ ],
+ ];
+
+ return (
+ <>
+
+
+ {/* ── Toolbar ── */}
+
+
+ {/* Block format select */}
+
+
+
+
+ {/* Formatting groups */}
+ {GROUPS.map((group, gi) => (
+
+ {group.map(({ cmd, Icon, title }) => (
+ { e.preventDefault(); exec(cmd); }}
+ >
+
+
+ ))}
+
+
+ ))}
+
+ {/* URL link */}
+ { e.preventDefault(); insertUrlLink(); }}
+ >
+
+
+
+ {/* Document link */}
+ { e.preventDefault(); openDocPicker(); }}
+ >
+
+
+
+
+
+ {/* Insert table */}
+ {
+ e.preventDefault();
+ tablePickerOpen ? setTablePickerOpen(false) : openTablePicker();
+ }}
+ >
+
+
+
+
+
+
+
+ {/* Inline code */}
+ { e.preventDefault(); toggleInlineCode(); }}
+ >
+
+
+
+ {/* Code block */}
+ { e.preventDefault(); insertCodeBlock(); }}
+ >
+
+
+
+
+ {/* ── Editable area ── */}
+ onChange(editorRef.current.innerHTML)}
+ className="typeset min-h-[120px] px-3 m-0 py-0 text-sm focus:outline-none"
+ />
+
+
+ {/* Table size picker */}
+ {tablePickerOpen && (
+ setTablePickerOpen(false)}
+ />
+ )}
+
+ {/* Document asset picker */}
+ {!readOnly && (
+
+ )}
+ >
+ );
+}
+
+// ─── TextBlock ────────────────────────────────────────────────────────────────
+
+export function TextBlock({ content, onUpdate, blockId, readOnly = false }) {
+ if (readOnly) {
+ return (
+
+ );
+ }
+ return (
+
+
+ onUpdate({ ...content, body: html })}
+ />
+
+ );
+}
\ No newline at end of file
diff --git a/apps/web/src/components/generic/Blocks/Admin/TextImageBlock.jsx b/apps/web/src/components/generic/Blocks/Admin/TextImageBlock.jsx
new file mode 100644
index 0000000..cd51534
--- /dev/null
+++ b/apps/web/src/components/generic/Blocks/Admin/TextImageBlock.jsx
@@ -0,0 +1,121 @@
+// components/generic/CMS/Blocks/TextImageBlock.jsx
+
+import { useState } from "react";
+import { ImageIcon } from "lucide-react";
+import { Label } from "@/components/ui/label";
+import { Input } from "@/components/ui/input";
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/components/ui/select";
+import { RichTextEditor } from "./TextBlock"; // reuse the shared editor
+import { AssetPickerSheet } from "../../AssetPickerSheet";
+import { useAssetPreviewSrc } from "@/hooks/useAssetPreviewSrc";
+import { MediaFallback } from "@/components/generic/MediaFallback";
+
+export function TextImageBlock({ content, onUpdate, blockId, readOnly = false }) {
+ const [pickerOpen, setPickerOpen] = useState(false);
+
+ // content.url is redacted (null) server-side for S3 assets — re-resolve
+ // through media.util.js instead of trusting the persisted url/thumbnail.
+ const { src, loading } = useAssetPreviewSrc(
+ { asset_id: content?.asset_id, storage_provider: content?.storage_provider, file_url: content?.url, thumbnail_url: content?.url },
+ { scope: "admin" },
+ );
+
+ return (
+
+
+ {/* ── Image position ── */}
+
+
+
+
+
+
+
+ {/* ── Text side — WYSIWYG ── */}
+
+
+ onUpdate({ ...content, body: html })}
+ />
+
+
+ {/* ── Image side ── */}
+
+
+
+ {loading ? (
+
+ ) : src ? (
+ setPickerOpen(true)}
+ >
+
+
+ Change Image
+
+
+ ) : (
+
+ )}
+
+ {content.asset_id && (
+
+
+ onUpdate({ ...content, alt: e.target.value })}
+ />
+
+ )}
+
+
+
+ {!readOnly && (
+ onUpdate({
+ ...content,
+ asset_id: asset.asset_id,
+ storage_provider: asset.storage_provider ?? null,
+ url: asset.file_url,
+ })}
+ />
+ )}
+
+ );
+}
\ No newline at end of file
diff --git a/apps/web/src/components/generic/Blocks/Admin/TextVideoBlock.jsx b/apps/web/src/components/generic/Blocks/Admin/TextVideoBlock.jsx
new file mode 100644
index 0000000..a885546
--- /dev/null
+++ b/apps/web/src/components/generic/Blocks/Admin/TextVideoBlock.jsx
@@ -0,0 +1,124 @@
+// components/generic/CMS/Blocks/TextVideoBlock.jsx
+
+import { useState } from "react";
+import { VideoIcon } from "lucide-react";
+import { Label } from "@/components/ui/label";
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/components/ui/select";
+import { RichTextEditor } from "./TextBlock"; // reuse the shared editor
+import { AssetPickerSheet } from "../../AssetPickerSheet";
+import { useAssetPreviewSrc } from "@/hooks/useAssetPreviewSrc";
+import { MediaFallback } from "@/components/generic/MediaFallback";
+
+export function TextVideoBlock({ content, onUpdate, blockId, readOnly = false }) {
+ const [pickerOpen, setPickerOpen] = useState(false);
+
+ // content.thumbnail_url is a presigned S3 URL captured at pick time for
+ // S3 assets — it expires. Re-resolve through media.util.js instead of
+ // trusting the persisted value, mirroring VideoBlock.jsx.
+ const { thumbnailUrl, loading } = useAssetPreviewSrc(
+ { asset_id: content?.asset_id, storage_provider: content?.storage_provider, file_url: content?.url, thumbnail_url: content?.thumbnail_url },
+ { scope: "admin" },
+ );
+ const thumb = thumbnailUrl ?? content.thumbnail_url ?? null;
+
+ return (
+
+
+ {/* ── Video position ── */}
+
+
+
+
+
+
+
+ {/* ── Text side — WYSIWYG ── */}
+
+
+ onUpdate({ ...content, body: html })}
+ />
+
+
+ {/* ── Video side ── */}
+
+
+
+ {loading ? (
+
+ ) : content.asset_id ? (
+ setPickerOpen(true)}
+ >
+ {thumb ? (
+
+ ) : (
+
+
+
+ )}
+
+ Change Video
+
+
+
+
+
+
+
+ ) : (
+
+ )}
+
+
+
+ {!readOnly && (
+ onUpdate({
+ ...content,
+ asset_id: asset.asset_id,
+ storage_provider: asset.storage_provider ?? null,
+ url: asset.file_url,
+ thumbnail_url: asset.thumbnail_url ?? null,
+ duration_seconds: Number(asset.duration) || 0,
+ })}
+ />
+ )}
+
+ );
+}
\ No newline at end of file
diff --git a/apps/web/src/components/generic/Blocks/Admin/VideoBlock.jsx b/apps/web/src/components/generic/Blocks/Admin/VideoBlock.jsx
new file mode 100644
index 0000000..417a50a
--- /dev/null
+++ b/apps/web/src/components/generic/Blocks/Admin/VideoBlock.jsx
@@ -0,0 +1,502 @@
+import { useRef, useState, useEffect, useCallback } from "react";
+import {
+ Play,
+ Pause,
+ SkipBack,
+ Volume2,
+ VolumeX,
+ Maximize2,
+ Minimize2,
+ VideoIcon,
+} from "lucide-react";
+import { Label } from "@/components/ui/label";
+import { AssetPickerSheet } from "../../AssetPickerSheet";
+import { useAssetPreviewSrc } from "@/hooks/useAssetPreviewSrc";
+import { MediaFallback } from "@/components/generic/MediaFallback";
+import { Spinner } from "@/components/ui/spinner";
+import { formatPlayerTime as fmtTime } from "@/utils/format.util";
+
+// ─── VideoBlock (Admin) ───────────────────────────────────────────────────────
+
+export function VideoBlock({ content, onUpdate, readOnly = false }) {
+ const [pickerOpen, setPickerOpen] = useState(false);
+
+ // content.url is redacted (null) server-side for S3 assets — see
+ // redactS3Url() in controllers/admin/assets.controller.js. Re-resolve
+ // through media.util.js instead of trusting the persisted url/thumbnail.
+ //
+ // thumbnail_url is intentionally NOT passed here: resolveAssetSrc()'s fast
+ // path falls back to thumbnail_url when there's no stream_token, which for
+ // a video asset with a redacted (null) file_url meant `src` resolved to
+ // the poster JPEG instead of the video file, and the browser then refused
+ // to play it ("media resource ... was not suitable"). Omitting it forces
+ // the async mint-token path, which resolves the real video stream src.
+ const { src, loading } = useAssetPreviewSrc(
+ { asset_id: content?.asset_id, storage_provider: content?.storage_provider, file_url: content?.url },
+ { scope: "admin" },
+ );
+ const poster = content?.thumbnail_url ?? undefined;
+
+ const vidRef = useRef(null);
+ const wrapRef = useRef(null);
+ const [playing, setPlaying] = useState(false);
+ const [progress, setProgress] = useState(0);
+ const [currentTime, setCurrentTime] = useState(0);
+ const [totalDuration, setTotalDuration] = useState(0);
+ const [muted, setMuted] = useState(false);
+ const [volume, setVolume] = useState(1);
+ const [overlayVisible,setOverlayVisible]= useState(true);
+ // Native Fullscreen API works on desktop (all browsers) and Android Chrome.
+ // iOS Safari doesn't support Fullscreen API on arbitrary elements at all, so
+ // pseudoFullscreen is a CSS-only (fixed inset-0) fallback that keeps our
+ // custom controls instead of falling back to native