name('assets.content')->middleware('signed:relative'); Route::prefix('v1')->group(function () { Route::get('/health', SystemHealthController::class); Route::get('/certificates/verify/{code}', [CertificateController::class, 'verify'])->middleware('throttle:60,1'); Route::post('/auth/login', [AuthController::class, 'login'])->middleware('throttle:login'); Route::post('/auth/forgot-password', [PasswordController::class, 'forgot'])->middleware('throttle:login'); Route::post('/auth/reset-password', [PasswordController::class, 'reset'])->middleware('throttle:login'); Route::post('/auth/invitations/accept', [InvitationController::class, 'accept'])->middleware('throttle:login'); Route::middleware('auth:sanctum')->group(function () { Route::get('/auth/me', [AuthController::class, 'me']); Route::post('/auth/logout', [AuthController::class, 'logout']); Route::get('/organizations', [OrganizationController::class, 'index']); Route::post('/organizations', [OrganizationController::class, 'store']); Route::get('/organizations/{organization}', [OrganizationController::class, 'show']); Route::patch('/organizations/{organization}', [OrganizationController::class, 'update']); Route::middleware('tenant')->group(function () { Route::post('/ai/chat', [AiChatController::class, 'chat'])->middleware('throttle:10,1'); Route::get('/organization-context', fn (TenantContext $tenant) => response()->json([ 'data' => [ 'id' => $tenant->id(), 'name' => $tenant->organization()->name, ], ])); Route::get('/learner/home', [LearnerController::class, 'home']); Route::get('/learner/progress', [LearnerController::class, 'progress']); Route::get('/learner/assignments/{assignment}', [LearnerController::class, 'show']); Route::post('/learner/events/sync', [LearnerController::class, 'sync']); Route::post('/learner/assignments/{assignment}/notes', [LearnerController::class, 'note']); Route::post('/learner/assignments/{assignment}/bookmarks', [LearnerController::class, 'bookmark']); Route::post('/learner/assignments/{assignment}/highlights', [LearnerController::class, 'highlight']); Route::post('/learner/assignments/{assignment}/favorite', [LearnerController::class, 'favorite']); Route::post('/learner/assignments/{assignment}/discussions', [LearnerController::class, 'discuss']); Route::post('/learner/discussions/{discussion}/reactions', [LearnerController::class, 'react']); Route::get('/manager/workspace', [ManagerWorkspaceController::class, 'show']); Route::get('/manager/assignment-contexts', [ManagerAssignmentController::class, 'contexts']); Route::get('/manager/assignments', [ManagerAssignmentController::class, 'index']); Route::post('/manager/assignments', [ManagerAssignmentController::class, 'store']); Route::patch('/manager/assignments/{assignment}/deadline', [ManagerAssignmentController::class, 'deadline']); Route::post('/manager/assignments/{assignment}/reminders', [ManagerAssignmentController::class, 'remind'])->middleware('throttle:20,1'); Route::get('/monitoring', [MonitoringController::class, 'show']); Route::post('/monitoring/rebuild', [MonitoringController::class, 'rebuild']); Route::get('/courses/{course}/analytics', [CourseAnalyticsController::class, 'show']); Route::get('/courses/{course}/analytics/report', [CourseAnalyticsController::class, 'report']); Route::get('/course-versions/{version}/collaboration', [CollaborationController::class, 'snapshot']); Route::post('/blocks/{block}/soft-lock', [CollaborationController::class, 'acquireLock']); Route::put('/blocks/{block}/soft-lock', [CollaborationController::class, 'renewLock']); Route::delete('/blocks/{block}/soft-lock', [CollaborationController::class, 'releaseLock']); Route::post('/course-versions/{version}/review-threads', [CollaborationController::class, 'createThread']); Route::post('/review-threads/{thread}/replies', [CollaborationController::class, 'reply']); Route::patch('/review-threads/{thread}/resolution', [CollaborationController::class, 'resolve']); Route::patch('/review-threads/{thread}/assignees', [CollaborationController::class, 'assign']); Route::post('/review-threads/{thread}/read', [CollaborationController::class, 'markRead']); Route::patch('/review-messages/{kind}/{message}', [CollaborationController::class, 'updateMessage']); Route::delete('/review-messages/{kind}/{message}', [CollaborationController::class, 'deleteMessage']); Route::post('/review-threads/{thread}/reactions', [CollaborationController::class, 'react']); Route::get('/review-center', [CollaborationController::class, 'reviewCenter']); Route::get('/notifications', [NotificationController::class, 'index']); Route::post('/notifications/{notification}/read', [NotificationController::class, 'read']); Route::delete('/notifications/{notification}', [NotificationController::class, 'dismiss']); Route::get('/preferences', [ProductSurfaceController::class, 'preferences']); Route::patch('/preferences', [ProductSurfaceController::class, 'updatePreferences']); Route::get('/organization-settings', [ProductSurfaceController::class, 'organizationSettings']); Route::patch('/organization-settings', [ProductSurfaceController::class, 'updateOrganizationSettings']); Route::get('/brand', [ProductSurfaceController::class, 'brand']); Route::patch('/brand', [ProductSurfaceController::class, 'updateBrand']); Route::get('/templates', [ProductSurfaceController::class, 'templates']); Route::post('/templates', [ProductSurfaceController::class, 'storeTemplate']); Route::patch('/templates/{template}', [ProductSurfaceController::class, 'updateTemplate']); Route::delete('/templates/{template}', [ProductSurfaceController::class, 'destroyTemplate']); Route::post('/templates/{template}/instantiate', [ProductSurfaceController::class, 'instantiateTemplate']); Route::get('/product-surfaces/{surface}', [ProductSurfaceController::class, 'surface']); Route::get('/exports', [ExportController::class, 'index']); Route::get('/exports/data/{type}', [ExportController::class, 'data']); Route::post('/exports/compatibility', [ExportController::class, 'compatibility']); Route::post('/exports', [ExportController::class, 'store']); Route::post('/exports/{export}/retry', [ExportController::class, 'retry']); Route::post('/exports/{export}/cancel', [ExportController::class, 'cancel']); Route::get('/exports/{export}/download', [ExportController::class, 'download']); Route::get('/certificates', [CertificateController::class, 'index']); Route::post('/certificate-templates', [CertificateController::class, 'storeTemplate']); Route::patch('/certificate-templates/{template}', [CertificateController::class, 'updateTemplate']); Route::delete('/certificate-templates/{template}', [CertificateController::class, 'archiveTemplate']); Route::post('/certificates/issue', [CertificateController::class, 'issue']); Route::post('/certificates/issue-bulk', [CertificateController::class, 'issueBulk']); Route::post('/certificates/{certificate}/revoke', [CertificateController::class, 'revoke']); Route::get('/certificates/{certificate}/download', [CertificateController::class, 'download']); Route::get('/ai-studio/jobs', [AiStudioController::class, 'index']); Route::get('/ai-settings', [AiStudioController::class, 'settings']); Route::patch('/ai-settings', [AiStudioController::class, 'updateSettings']); Route::post('/ai-settings/health', [AiStudioController::class, 'health'])->middleware('throttle:10,1'); Route::get('/ai-connections', [AiConnectionController::class, 'index']); Route::post('/ai-connections', [AiConnectionController::class, 'store']); Route::patch('/ai-connections/{connection}', [AiConnectionController::class, 'update']); Route::delete('/ai-connections/{connection}', [AiConnectionController::class, 'destroy']); Route::post('/ai-connections/{connection}/default', [AiConnectionController::class, 'makeDefault']); Route::post('/ai-connections/{connection}/test', [AiConnectionController::class, 'test'])->middleware('throttle:10,1'); Route::post('/ai-connections/{connection}/models', [AiConnectionController::class, 'discover'])->middleware('throttle:10,1'); Route::post('/ai-studio/jobs', [AiStudioController::class, 'store'])->middleware('throttle:10,1'); Route::get('/ai-studio/jobs/{job}', [AiStudioController::class, 'show']); Route::post('/ai-studio/jobs/{job}/cancel', [AiStudioController::class, 'cancel']); Route::post('/ai-studio/jobs/{job}/retry', [AiStudioController::class, 'retry'])->middleware('throttle:10,1'); Route::post('/ai-studio/assist', [AiStudioController::class, 'assist'])->middleware('throttle:10,1'); Route::post('/ai-studio/taxonomy-suggestions', [AiStudioController::class, 'taxonomySuggestions']); Route::post('/ai-studio/suggestions/{suggestion}/accept', [AiStudioController::class, 'accept']); Route::post('/ai-studio/suggestions/{suggestion}/reject', [AiStudioController::class, 'reject']); Route::get('/taxonomy-types', [TaxonomyTypeController::class, 'index']); Route::post('/taxonomy-types', [TaxonomyTypeController::class, 'store']); Route::get('/taxonomy-nodes', [TaxonomyNodeController::class, 'index']); Route::post('/taxonomy-nodes', [TaxonomyNodeController::class, 'store']); Route::patch('/taxonomy-nodes/{node}', [TaxonomyNodeController::class, 'update']); Route::get('/content-mappings', [ContentMappingController::class, 'index']); Route::post('/content-mappings', [ContentMappingController::class, 'store']); Route::delete('/content-mappings/{mapping}', [ContentMappingController::class, 'destroy']); Route::get('/taxonomy-workspace', [TaxonomyWorkspaceController::class, 'index']); Route::post('/competency-frameworks', [TaxonomyWorkspaceController::class, 'storeFramework']); Route::patch('/competency-frameworks/{framework}', [TaxonomyWorkspaceController::class, 'updateFramework']); Route::put('/competency-frameworks/{framework}/items', [TaxonomyWorkspaceController::class, 'syncItems']); Route::delete('/competency-frameworks/{framework}', [TaxonomyWorkspaceController::class, 'destroyFramework']); Route::get('/assets', [AssetController::class, 'index']); Route::get('/assets/{asset}', [AssetController::class, 'show']); Route::post('/assets', [AssetController::class, 'store']); Route::delete('/assets/{asset}', [AssetController::class, 'destroy']); Route::get('/assessment-contexts', [AssessmentController::class, 'contexts']); Route::get('/assessments', [AssessmentController::class, 'index']); Route::post('/assessments', [AssessmentController::class, 'store']); Route::get('/assessments/{assessment}', [AssessmentController::class, 'show']); Route::patch('/assessments/{assessment}', [AssessmentController::class, 'update']); Route::delete('/assessments/{assessment}', [AssessmentController::class, 'destroy']); Route::post('/assessments/{assessment}/questions', [AssessmentController::class, 'storeQuestion']); Route::put('/assessments/{assessment}/questions/order', [AssessmentController::class, 'reorderQuestions']); Route::patch('/questions/{question}', [AssessmentController::class, 'updateQuestion']); Route::delete('/questions/{question}', [AssessmentController::class, 'destroyQuestion']); Route::get('/question-bank', [QuestionBankController::class, 'index']); Route::post('/question-bank', [QuestionBankController::class, 'store']); Route::patch('/question-bank/{question}', [QuestionBankController::class, 'update']); Route::delete('/question-bank/{question}', [QuestionBankController::class, 'destroy']); Route::get('/question-categories', [QuestionCategoryController::class, 'index']); Route::post('/question-categories', [QuestionCategoryController::class, 'store']); Route::delete('/question-categories/{category}', [QuestionCategoryController::class, 'destroy']); Route::get('/users', [UserController::class, 'index']); Route::get('/users/import-template', [UserController::class, 'template']); Route::post('/users/import', [UserController::class, 'import']); Route::patch('/users/{user}', [UserController::class, 'update']); Route::post('/user-invitations', [InvitationController::class, 'store']); Route::get('/user-invitations', [InvitationController::class, 'index']); Route::post('/user-invitations/{invitation}/resend', [InvitationController::class, 'resend']); Route::delete('/user-invitations/{invitation}', [InvitationController::class, 'revoke']); Route::get('/teams', [TeamController::class, 'index']); Route::post('/teams', [TeamController::class, 'store']); Route::get('/teams/{team}', [TeamController::class, 'show']); Route::patch('/teams/{team}', [TeamController::class, 'update']); Route::put('/teams/{team}/members', [TeamController::class, 'attachMember']); Route::put('/teams/{team}/managers', [TeamController::class, 'attachManager']); Route::delete('/teams/{team}/members/{user}', [TeamController::class, 'detachMember']); Route::delete('/teams/{team}/managers/{user}', [TeamController::class, 'detachManager']); Route::get('/subscription', [SubscriptionController::class, 'current']); Route::get('/courses', [CourseController::class, 'index']); Route::post('/courses', [CourseController::class, 'store']); Route::get('/courses/{course}', [CourseController::class, 'show']); Route::patch('/courses/{course}', [CourseController::class, 'update']); Route::post('/courses/{course}/bookmark', [CourseController::class, 'toggleBookmark']); Route::post('/courses/{course}/archive', [CourseController::class, 'archive']); Route::get('/courses/{course}/versions', [CourseVersionController::class, 'index']); Route::get('/courses/{course}/versions/compare', [CourseVersionController::class, 'compare']); Route::patch('/courses/{course}/versions/{version}', [CourseController::class, 'updateVersion']); Route::post('/courses/{course}/versions/{version}/fork', [CourseController::class, 'fork']); Route::get('/courses/{course}/versions/{version}/readiness', [CoursePublicationController::class, 'readiness']); Route::put('/courses/{course}/versions/{version}/completion-rules', [CoursePublicationController::class, 'configure']); Route::post('/courses/{course}/versions/{version}/review', [CoursePublicationController::class, 'submitReview']); Route::post('/courses/{course}/versions/{version}/return-to-draft', [CoursePublicationController::class, 'returnDraft']); Route::post('/courses/{course}/versions/{version}/publish', [CoursePublicationController::class, 'publish']); Route::post('/courses/{course}/versions/{version}/schedule', [CoursePublicationController::class, 'schedule']); Route::delete('/courses/{course}/versions/{version}/schedule', [CoursePublicationController::class, 'cancelSchedule']); Route::post('/courses/{course}/versions/{version}/unpublish', [CoursePublicationController::class, 'unpublish']); Route::get('/assignment-contexts', [AssignmentController::class, 'contexts']); Route::post('/assignment-audience-import', [AssignmentController::class, 'importAudience']); Route::get('/assignments', [AssignmentController::class, 'index']); Route::post('/assignments', [AssignmentController::class, 'store']); Route::post('/assignments/bulk', [AssignmentController::class, 'bulk']); Route::get('/assignments/{assignment}', [AssignmentController::class, 'show']); Route::patch('/assignments/{assignment}', [AssignmentController::class, 'update']); Route::post('/assignments/{assignment}/reminders', [AssignmentController::class, 'remind'])->middleware('throttle:20,1'); Route::post('/assignments/sync', [AssignmentController::class, 'sync']); Route::post('/assignments/{assignment}/cancel', [AssignmentController::class, 'cancel']); Route::get('/learning-path-contexts', [LearningPathController::class, 'contexts']); Route::get('/learning-paths', [LearningPathController::class, 'index']); Route::post('/learning-paths', [LearningPathController::class, 'store']); Route::get('/learning-paths/{path}', [LearningPathController::class, 'show']); Route::patch('/learning-paths/{path}/versions/{version}', [LearningPathController::class, 'update']); Route::post('/learning-paths/{path}/versions/{version}/items', [LearningPathController::class, 'addItem']); Route::put('/learning-paths/{path}/versions/{version}/items/order', [LearningPathController::class, 'reorder']); Route::delete('/learning-path-items/{item}', [LearningPathController::class, 'removeItem']); Route::post('/learning-paths/{path}/versions/{version}/review', [LearningPathController::class, 'submitReview']); Route::post('/learning-paths/{path}/versions/{version}/publish', [LearningPathController::class, 'publish']); Route::post('/learning-paths/{path}/versions/{version}/fork', [LearningPathController::class, 'fork']); Route::post('/course-versions/{version}/modules', [CourseStructureController::class, 'storeModule']); Route::put('/course-versions/{version}/modules/order', [CourseStructureController::class, 'reorderModules']); Route::patch('/course-modules/{module}', [CourseStructureController::class, 'updateModule']); Route::post('/course-modules/{module}/duplicate', [CourseStructureController::class, 'duplicateModule']); Route::delete('/course-modules/{module}', [CourseStructureController::class, 'destroyModule']); Route::post('/course-modules/{module}/lessons', [CourseStructureController::class, 'storeLesson']); Route::put('/course-modules/{module}/lessons/order', [CourseStructureController::class, 'reorderLessons']); Route::patch('/lessons/{lesson}', [CourseStructureController::class, 'updateLesson']); Route::post('/lessons/{lesson}/duplicate', [CourseStructureController::class, 'duplicateLesson']); Route::delete('/lessons/{lesson}', [CourseStructureController::class, 'destroyLesson']); Route::get('/block-registry', [CourseBuilderController::class, 'registry']); Route::get('/courses/{course}/versions/{version}/lessons/{lesson}/builder', [CourseBuilderController::class, 'show']); Route::post('/courses/{course}/versions/{version}/lessons/{lesson}/blocks', [CourseBuilderController::class, 'store']); Route::patch('/blocks/{block}', [CourseBuilderController::class, 'update']); Route::post('/blocks/{block}/duplicate', [CourseBuilderController::class, 'duplicate']); Route::delete('/blocks/{block}', [CourseBuilderController::class, 'destroy']); Route::put('/lessons/{lesson}/blocks/order', [CourseBuilderController::class, 'reorder']); }); Route::get('/platform/overview', [ProductSurfaceController::class, 'platform']); Route::get('/platform/usage', [PlatformOperationsController::class, 'usage']); Route::get('/platform/storage', [PlatformOperationsController::class, 'storage']); Route::get('/platform/ai', [PlatformOperationsController::class, 'ai']); Route::get('/platform/health', [PlatformOperationsController::class, 'health']); Route::get('/platform/jobs', [PlatformOperationsController::class, 'jobs']); Route::get('/platform/backups', [PlatformOperationsController::class, 'backups']); Route::get('/platform/audit', [PlatformGovernanceController::class, 'audit']); Route::get('/platform/administrators', [PlatformGovernanceController::class, 'administrators']); Route::match(['get', 'patch'], '/platform/settings', [ProductSurfaceController::class, 'platformSettings']); Route::get('/platform/subscriptions', [PlatformSubscriptionController::class, 'index']); Route::post('/platform/subscriptions', [PlatformSubscriptionController::class, 'store']); Route::patch('/platform/subscriptions/{subscription}', [PlatformSubscriptionController::class, 'update']); Route::get('/platform/plans', [PlatformPlanController::class, 'index']); Route::post('/platform/plans', [PlatformPlanController::class, 'store']); Route::patch('/platform/plans/{plan}', [PlatformPlanController::class, 'update']); Route::get('/platform/organizations/{organization}/plan', [PlatformOrganizationPlanController::class, 'show']); Route::patch('/platform/organizations/{organization}/plan', [PlatformOrganizationPlanController::class, 'update']); }); });