PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 2.1.0
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v2.1.0
2.1.0 2.0.15 2.0.12 2.0.10 2.0.4 2.0.1 2.0.0 1.95.3 1.95.2 1.95 1.91.6 trunk 1.11 1.12 1.13 1.20 1.21 1.22 1.23 1.30 1.31 1.32 1.35 1.40 1.41 All 42 releases
← All changes | app/Http/Routes/api.php +65 -7 1.91.62.1.0 View file →
@@ -1,13 +1,17 @@
1 1 <?php
2 2 //if accessed directly exit
3 3 if (!defined('ABSPATH')) exit;
4 4
5 +use FluentBoards\App\Http\Controllers\AiController;
5 6 use FluentBoards\App\Http\Controllers\BoardController;
6 7 use FluentBoards\App\Http\Controllers\CommentController;
8 +use FluentBoards\App\Http\Controllers\FolderController;
7 9 use FluentBoards\App\Http\Controllers\LabelController;
10 +use FluentBoards\App\Http\Controllers\MCPSettingsController;
8 11 use FluentBoards\App\Http\Controllers\NotificationController;
9 12 use FluentBoards\App\Http\Controllers\OptionsController;
13 +use FluentBoards\App\Http\Controllers\PublicBoardController;
10 14 use FluentBoards\App\Http\Controllers\ReportController;
11 15 use FluentBoards\App\Http\Controllers\StageController;
12 16 use FluentBoards\App\Http\Controllers\TaskController;
13 17 use FluentBoards\App\Http\Controllers\UserController;
@@ -23,9 +27,8 @@
23 27 $router->get('/crm-associated-tasks/{associated_id}', [TaskController::class, 'getAssociatedTasks'])->int('associated_id');
24 28 $router->get('/stage/{task_id}', [TaskController::class, 'getStageByTask']); //FUTURE: this api need to be relocated
25 29
26 30 $router->get('/boards-by-type/{type}', [BoardController::class, 'getBoardsByType']);
27 - $router->get('/{task_id}/labels', [TaskController::class, 'getLabelsByTask']);
28 31
29 32 // Task tabs configuration
30 33 $router->get('/task-tabs/config', [TaskController::class, 'getTaskTabsConfig']);
31 34 $router->post('/task-tabs/config', [TaskController::class, 'saveTaskTabsConfig']);
@@ -32,9 +35,9 @@
32 35 });
33 36
34 37 $router->withPolicy('BoardUserPolicy')->group(function ($router) {
35 38
36 - $router->get('/quick-search', [OptionsController::class, 'quickSearch']);
39 + $router->get('/global-search', [OptionsController::class, 'globalSearch']);
37 40
38 41 $router->get('/member-associated-users/{id}', [UserController::class, 'memberAssociatedTaskUsers']);
39 42 $router->get('ajax-options', [OptionsController::class, 'selectorOptions']);
40 43 $router->post('update-global-notification-settings', [OptionsController::class, 'updateGlobalNotificationSettings']);
@@ -40,10 +43,13 @@
40 43 $router->post('update-global-notification-settings', [OptionsController::class, 'updateGlobalNotificationSettings']);
41 44 $router->get('get-global-notification-settings', [OptionsController::class, 'getGlobalNotificationSettings']);
42 45 $router->put('update-dashboard-view-settings', [OptionsController::class, 'updateDashboardViewSettings']);
43 46 $router->get('get-dashboard-view-settings', [OptionsController::class, 'getDashboardViewSettings']);
44 - $router->get('projects/reports', [ReportController::class, 'getBoardReports']);
45 47 $router->get('reports/timesheet', [ReportController::class, 'getTimeSheetReport']);
48 + $router->get('reports/overview', [ReportController::class, 'getOverviewReport']);
49 + $router->get('reports/tasks', [ReportController::class, 'getTasksReport']);
50 + $router->get('reports/activity', [ReportController::class, 'getActivityReport']);
51 + $router->get('reports/roadmap', [ReportController::class, 'getRoadmapReport']);
46 52
47 53 });
48 54
49 55 $router->prefix('projects')->withPolicy('AuthPolicy')->group(function ($router) {
@@ -49,11 +55,12 @@
49 55 $router->prefix('projects')->withPolicy('AuthPolicy')->group(function ($router) {
50 56 $router->get('/', [BoardController::class, 'getBoards']);
51 57 $router->post('/', [BoardController::class, 'create']);
52 58 $router->get('/get-default-board-colors', [BoardController::class, 'getBoardDefaultBackgroundColors']);
59 + // NOTE: The global "Add" (board/stage/task) drawer was removed from the v2 UI. This endpoint is NOT dedicated to that feature — it remains in active use by other components, so it must stay.
53 60 $router->get('/list-of-boards', [BoardController::class, 'getBoardsList']); // it is using for to get all boards by user
54 61 $router->get('/user-accessible-boards', [BoardController::class, 'getOnlyBoardsByUser']);
55 - $router->get('/crm-associated-boards/{id}', [BoardController::class, 'getAssociatedBoards'])->int('associated_id');
62 + $router->get('/crm-associated-boards/{associated_id}', [BoardController::class, 'getAssociatedBoards'])->int('associated_id');
56 63 $router->get('/currencies', [BoardController::class, 'getCurrencies']);
57 64 $router->get('/user-admin-in-boards', [BoardController::class, 'getUsersOfBoards']);
58 65 $router->get('/recent-boards', [BoardController::class, 'getRecentBoards']);
59 66 $router->get('/pinned-boards', [BoardController::class, 'getPinnedBoards']);
@@ -88,8 +95,9 @@
88 95 $router->get('/assignees', [BoardController::class, 'getAssigneesByBoard'])->int('board_id');
89 96 $router->get('/activities', [BoardController::class, 'getActivities'])->int('board_id');
90 97
91 98 $router->put('/stage-move-all-task', [BoardController::class, 'moveAllTasks'])->int('board_id');
99 + // NOTE: The global "Add" drawer was removed from the v2 UI. This stage-create endpoint is shared (in-board stage creation still uses it), so it must stay.
92 100 $router->post('/stage-create', [BoardController::class, 'createStage'])->int('board_id');
93 101 $router->put('/stage/{stage_id}/sort-task', [StageController::class, 'sortStageTasks'])->int('board_id')->int('stage_id');
94 102 $router->put('/stage/{stage_id}/archive-all-task', [BoardController::class, 'archiveAllTasksInStage'])->int('board_id')->int('stage_id');
95 103 $router->put('/re-position-stages', [BoardController::class, 'repositionStages'])->int('board_id');
@@ -106,9 +114,8 @@
106 114 $router->get('/stage-task-available-positions/{stage_id}', [BoardController::class, 'getStageTaskAvailablePositions'])->int('board_id')->int('stage_id');
107 115
108 116 $router->post('/crm-contact', [BoardController::class, 'updateAssociateCrmContact'])->int('board_id');
109 117 $router->get('/crm-contacts', [BoardController::class, 'getAssociateCrmContacts'])->int('board_id');
110 - $router->delete('/crm-contact/{contact_id}', [BoardController::class, 'deleteAssociateCrmContact'])->int('board_id')->int('contact_id');
111 118
112 119 $router->get('/notification-settings', [NotificationController::class, 'getBoardNotificationSettings'])->int('board_id');
113 120 $router->put('/update-notification-settings', [NotificationController::class, 'updateBoardNotificationSettings'])->int('board_id');
114 121
@@ -119,9 +126,10 @@
119 126 $router->post('/upload/background-image', [BoardController::class, 'uploadBoardBackground'])->int('board_id');
120 127 $router->put('/archive-board', [BoardController::class, 'archiveBoard'])->int('board_id');
121 128 $router->put('/restore-board', [BoardController::class, 'restoreBoard'])->int('board_id');
122 129 $router->get('/board-menu-items', [BoardController::class, 'getBoardMenuItems'])->int('board_id');
123 - $router->get('/stage-wise-reports', [ReportController::class, 'getStageWiseBoardReports'])->int('board_id');
130 + $router->get('/public-access-settings', [BoardController::class, 'getPublicAccessSettings'])->int('board_id');
131 + $router->put('/toggle-public-access', [BoardController::class, 'togglePublicAccess'])->int('board_id');
124 132
125 133
126 134 //# Tasks under a single board routes
127 135 //# Route prefix: /projects/{id}/tasks
@@ -126,14 +134,21 @@
126 134 //# Tasks under a single board routes
127 135 //# Route prefix: /projects/{id}/tasks
128 136 $router->prefix('/tasks')->group(function ($router) {
129 137 $router->get('/', [TaskController::class, 'getTasksByBoard'])->int('board_id');
138 + $router->get('/filtered', [TaskController::class, 'getFilteredBoardTasks'])->int('board_id');
139 + $router->get('/table', [TaskController::class, 'getTableTasks'])->int('board_id');
130 140 $router->get('/by-stage', [TaskController::class, 'getTasksByBoardStage'])->int('board_id');
141 + $router->get('/stage-page', [TaskController::class, 'getStageTasksPage'])->int('board_id');
142 + // NOTE: The global "Add" drawer was removed from the v2 UI. This is the primary task-create endpoint used throughout the app, so it must stay.
131 143 $router->post('/', [TaskController::class, 'create']);
132 144 $router->post('/create-task-from-image', [TaskController::class, 'createTaskFromImage'])->int('board_id');
133 145 $router->get('/archived', [TaskController::class, 'getArchivedTasks'])->int('board_id');
134 146 $router->get('/{task_id}', [TaskController::class, 'find'])->int('board_id')->int('task_id')->int('task_id');
135 147 $router->put('/{task_id}', [TaskController::class, 'updateTaskProperties'])->int('board_id')->int('task_id');
148 + $router->delete('/{task_id}/support-ticket', [TaskController::class, 'removeSupportTicketLink'])
149 + ->int('board_id')
150 + ->int('task_id');
136 151 $router->post('/{task_id}/dates', [TaskController::class, 'updateTaskDates'])->int('board_id')->int('task_id');
137 152 $router->put('/{task_id}/move-task', [TaskController::class, 'moveTask'])->int('board_id')->int('task_id');
138 153 $router->post('/bulk-actions', [TaskController::class, 'bulkActions'])->int('board_id');
139 154 $router->post('/update-cover-photo/{task_id}', [TaskController::class, 'updateTaskCoverPhoto'])->int('task_id');
@@ -139,9 +154,16 @@
139 154 $router->post('/update-cover-photo/{task_id}', [TaskController::class, 'updateTaskCoverPhoto'])->int('task_id');
140 155 $router->post('/status-update/{task_id}', [TaskController::class, 'taskStatusUpdate'])->int('task_id');
141 156 $router->delete('/{task_id}', [TaskController::class, 'deleteTask'])->int('board_id')->int('task_id');
142 157 $router->put('/{task_id}/move-to-next-stage', [TaskController::class, 'moveTaskToNextStage'])->int('board_id')->int('task_id');
158 + $router->put('/{task_id}/pin', [TaskController::class, 'toggleTaskPinned'])->int('board_id')->int('task_id');
143 159
160 + // AI task intelligence (summarize / subtasks / suggestions) — board-scoped.
161 + $router->post('/{task_id}/ai-assist', [AiController::class, 'taskAssist'])->int('board_id')->int('task_id');
162 + // Transactional batch apply for AI label/priority suggestions (all-or-nothing).
163 + // Bulk subtask creation lives with the other subtask APIs in Fluent Boards Pro.
164 + $router->post('/{task_id}/ai-apply-suggestions', [AiController::class, 'applySuggestions'])->int('board_id')->int('task_id');
165 +
144 166 // Comments Routes Area
145 167 $router->get('/{task_id}/comments', [CommentController::class, 'getComments'])->int('board_id')->int('task_id');
146 168 $router->post('/{task_id}/comments', [CommentController::class, 'create'])->int('board_id')->int('task_id');
147 169 $router->put('/comments/{comment_id}', [CommentController::class, 'update'])->int('board_id')->int('comment_id');
@@ -173,12 +195,39 @@
173 195
174 196 $router->get('/general-settings', [OptionsController::class, 'getGeneralSettings']);
175 197 $router->post('/general-settings', [OptionsController::class, 'saveGeneralSettings']);
176 198
199 + $router->get('/mcp/status', [MCPSettingsController::class, 'status']);
200 + $router->post('/mcp/toggle', [MCPSettingsController::class, 'toggle']);
201 + $router->post('/mcp/install-adapter', [MCPSettingsController::class, 'installAdapter']);
202 + $router->get('/mcp/config-snippet', [MCPSettingsController::class, 'getConfigSnippet']);
203 +
177 204 $router->get('pages', [OptionsController::class, 'getPages']);
178 205
206 + $router->prefix('folders')->group(function ($router) {
207 + $router->get('/', [FolderController::class, 'getFolders']);
208 + $router->post('/', [FolderController::class, 'createFolder']);
209 + $router->prefix('/{folder_id}')->group(function ($router) {
210 + $router->get('/', [FolderController::class, 'getFolderById'])->int('folder_id');
211 + $router->post('/add-board', [FolderController::class, 'addBoardToFolder'])->int('folder_id');
212 + $router->post('/remove-board', [FolderController::class, 'removeBoardFromFolder'])->int('folder_id');
213 + $router->put('/', [FolderController::class, 'updateFolder'])->int('folder_id');
214 + $router->delete('/', [FolderController::class, 'deleteFolder'])->int('folder_id');
215 + });
216 + });
217 +
179 218 });
180 219
220 +// AI writing assistant. Settings routes are admin-only; `generate` is open to
221 +// any authenticated user (enforced per-method inside AiPolicy).
222 +$router->prefix('ai')->withPolicy('AiPolicy')->group(function ($router) {
223 + $router->get('/settings', [AiController::class, 'getSettings']);
224 + $router->post('/settings', [AiController::class, 'saveSettings']);
225 + $router->post('/models', [AiController::class, 'getModels']);
226 + $router->post('/test', [AiController::class, 'testConnection']);
227 + $router->post('/generate', [AiController::class, 'generate']);
228 +});
229 +
181 230 $router->prefix('webhooks')->withPolicy('WebhookPolicy')->group(function ($router) {
182 231 $router->get('/', [WebhookController::class, 'index']);
183 232 $router->post('/', [WebhookController::class, 'create']);
184 233 $router->put('/{id}', [WebhookController::class, 'update'])->int('id');
@@ -197,9 +246,11 @@
197 246 $router->prefix('member/{id}')->withPolicy('UserPolicy')->group(function ($router) {
198 247 $router->get('/', [UserController::class, 'getMemberInfo']);
199 248 $router->get('/projects', [UserController::class, 'getMemberBoards']);
200 249 $router->get('/tasks', [UserController::class, 'getMemberAssociatedTasks']);
250 + $router->get('/task-counts', [UserController::class, 'getMemberTaskCounts']);
201 251 $router->get('/activities', [UserController::class, 'getMemberRelatedAcitivies']);
252 + $router->get('/stats', [UserController::class, 'getMemberStats']);
202 253 });
203 254
204 255 /*
205 256 * TODO: I guess we can minimize the number of routes. and Backend code needs to be refactored
@@ -216,11 +267,18 @@
216 267 $router->prefix('contacts/{board_id}')->withPolicy('SingleBoardPolicy')->group(function ($router) {
217 268 $router->get('/', [TaskController::class, 'getAssociatedCrmContacts'])->int('board_id');
218 269 });
219 270
271 +$router->prefix('public/boards/{board_id}')->withPolicy('PublicBoardPolicy')->group(function ($router) {
272 + $router->get('/', [PublicBoardController::class, 'find'])->int('board_id');
273 + $router->get('/tasks', [PublicBoardController::class, 'getTasksByBoard'])->int('board_id');
274 + $router->get('/tasks/by-stage', [PublicBoardController::class, 'getTasksByBoardStage'])->int('board_id');
275 + $router->get('/tasks/stage-page', [PublicBoardController::class, 'getStageTasksPage'])->int('board_id');
276 +});
277 +
220 278 // User utility routes
221 279 $router->withPolicy('UserPolicy')->group(function ($router) {
222 - $router->get('/quick-search', [OptionsController::class, 'quickSearch']);
280 + $router->get('/global-search', [OptionsController::class, 'globalSearch']);
223 281 });
224 282
225 283
226 284 $router->prefix('options')->withPolicy('AuthPolicy')->group(function ($router) {