PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 2.0.10
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v2.0.10
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 1.45 All 41 releases
fluent-boards / app / Http / Routes / api.php

api.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 2.0.10, at app/Http/Routes/api.php

289 lines 19.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 //if accessed directly exit
3 if (!defined('ABSPATH')) exit;
4
5 use FluentBoards\App\Http\Controllers\AiController;
6 use FluentBoards\App\Http\Controllers\BoardController;
7 use FluentBoards\App\Http\Controllers\CommentController;
8 use FluentBoards\App\Http\Controllers\FolderController;
9 use FluentBoards\App\Http\Controllers\LabelController;
10 use FluentBoards\App\Http\Controllers\MCPSettingsController;
11 use FluentBoards\App\Http\Controllers\NotificationController;
12 use FluentBoards\App\Http\Controllers\OptionsController;
13 use FluentBoards\App\Http\Controllers\PublicBoardController;
14 use FluentBoards\App\Http\Controllers\ReportController;
15 use FluentBoards\App\Http\Controllers\StageController;
16 use FluentBoards\App\Http\Controllers\TaskController;
17 use FluentBoards\App\Http\Controllers\UserController;
18 use FluentBoards\App\Http\Controllers\WebhookController;
19
20
21 /**
22 * @var $router \FluentBoards\Framework\Http\Router
23 */
24
25 $router->prefix('tasks')->withPolicy('AuthPolicy')->group(function ($router) {
26 $router->get('/top-in-boards', [TaskController::class, 'getTopTasksForBoards']);
27 $router->get('/crm-associated-tasks/{associated_id}', [TaskController::class, 'getAssociatedTasks'])->int('associated_id');
28 $router->get('/stage/{task_id}', [TaskController::class, 'getStageByTask']); //FUTURE: this api need to be relocated
29
30 $router->get('/boards-by-type/{type}', [BoardController::class, 'getBoardsByType']);
31
32 // Task tabs configuration
33 $router->get('/task-tabs/config', [TaskController::class, 'getTaskTabsConfig']);
34 $router->post('/task-tabs/config', [TaskController::class, 'saveTaskTabsConfig']);
35 });
36
37 $router->withPolicy('BoardUserPolicy')->group(function ($router) {
38
39 $router->get('/global-search', [OptionsController::class, 'globalSearch']);
40
41 $router->get('/member-associated-users/{id}', [UserController::class, 'memberAssociatedTaskUsers']);
42 $router->get('ajax-options', [OptionsController::class, 'selectorOptions']);
43 $router->post('update-global-notification-settings', [OptionsController::class, 'updateGlobalNotificationSettings']);
44 $router->get('get-global-notification-settings', [OptionsController::class, 'getGlobalNotificationSettings']);
45 $router->put('update-dashboard-view-settings', [OptionsController::class, 'updateDashboardViewSettings']);
46 $router->get('get-dashboard-view-settings', [OptionsController::class, 'getDashboardViewSettings']);
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']);
52
53 });
54
55 $router->prefix('projects')->withPolicy('AuthPolicy')->group(function ($router) {
56 $router->get('/', [BoardController::class, 'getBoards']);
57 $router->post('/', [BoardController::class, 'create']);
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.
60 $router->get('/list-of-boards', [BoardController::class, 'getBoardsList']); // it is using for to get all boards by user
61 $router->get('/user-accessible-boards', [BoardController::class, 'getOnlyBoardsByUser']);
62 $router->get('/crm-associated-boards/{associated_id}', [BoardController::class, 'getAssociatedBoards'])->int('associated_id');
63 $router->get('/currencies', [BoardController::class, 'getCurrencies']);
64 $router->get('/user-admin-in-boards', [BoardController::class, 'getUsersOfBoards']);
65 $router->get('/recent-boards', [BoardController::class, 'getRecentBoards']);
66 $router->get('/pinned-boards', [BoardController::class, 'getPinnedBoards']);
67
68 $router->post('/onboard', [BoardController::class, 'createFirstBoard']);
69 $router->put('/skip-onboarding', [BoardController::class, 'skipOnboarding']);
70
71
72 });
73
74 $router->prefix('projects/{board_id}')->withPolicy('SingleBoardPolicy')->group(function ($router) {
75 $router->get('/', [BoardController::class, 'find'])->int('board_id');
76 $router->get('/has-data-changed', [BoardController::class, 'hasDataChanged'])->int('board_id');
77 $router->put('/update-board-properties', [BoardController::class, 'updateBoardProperties'])->int('board_id');
78 $router->put('/', [BoardController::class, 'update'])->int('board_id');
79 $router->delete('/', [BoardController::class, 'delete'])->int('board_id');
80 $router->get('/labels', [LabelController::class, 'getLabelsByBoard']);
81 $router->post('/labels', [LabelController::class, 'createLabel']);
82 $router->get('/labels/used-in-tasks', [LabelController::class, 'getLabelsByBoardUsedInTasks']);
83 $router->get('/tasks/{task_id}/labels', [LabelController::class, 'getLabelsByTask']); //FUTURE: these api need to be relocated
84 $router->post('/labels/task', [LabelController::class, 'createLabelForTask']);
85 $router->put('/labels/{label_id}', [LabelController::class, 'editLabelofBoard']);
86 $router->delete('/labels/{label_id}', [LabelController::class, 'deleteLabelOfBoard']);
87 $router->delete('/tasks/{task_id}/labels/{label_id}', [LabelController::class, 'deleteLabelOfTask']);
88 $router->put('/pin-board', [BoardController::class, 'pinBoard']);
89 $router->put('/unpin-board', [BoardController::class, 'unpinBoard']);
90
91 $router->get('/users', [BoardController::class, 'getBoardUsers']);
92 $router->post('/user/{user_id}/remove', [BoardController::class, 'removeUserFromBoard'])->int('board_id')->int('user_id');
93 $router->post('/add-members', [BoardController::class, 'addMembersInBoard']);
94
95 $router->get('/assignees', [BoardController::class, 'getAssigneesByBoard'])->int('board_id');
96 $router->get('/activities', [BoardController::class, 'getActivities'])->int('board_id');
97
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.
100 $router->post('/stage-create', [BoardController::class, 'createStage'])->int('board_id');
101 $router->put('/stage/{stage_id}/sort-task', [StageController::class, 'sortStageTasks'])->int('board_id')->int('stage_id');
102 $router->put('/stage/{stage_id}/archive-all-task', [BoardController::class, 'archiveAllTasksInStage'])->int('board_id')->int('stage_id');
103 $router->put('/re-position-stages', [BoardController::class, 'repositionStages'])->int('board_id');
104 $router->put('/update-stage/{stage_id}', [StageController::class, 'updateStage'])->int('board_id'); //Todo:: will delete later
105 $router->put('/update-stage-property/{stage_id}', [StageController::class, 'updateStageProperty'])->int('board_id');
106 $router->put('/archive-stage/{stage_id}', [BoardController::class, 'archiveStage'])->int('board_id');
107 $router->put('/stage-view/{stage_id}', [BoardController::class, 'changeStageView'])->int('board_id');
108 $router->put('/restore-stage/{stage_id}', [BoardController::class, 'restoreStage'])->int('board_id');
109 $router->put('/drag-stage', [StageController::class, 'dragStage'])->int('board_id');
110 $router->get('/archived-stages', [BoardController::class, 'getArchivedStage'])->int('board_id');
111 $router->get('/archived-tasks', [TaskController::class, 'getArchivedTasks'])->int('board_id');
112 $router->put('/bulk-restore-tasks', [TaskController::class, 'bulkRestoreTasks'])->int('board_id');
113 $router->delete('/bulk-delete-tasks', [TaskController::class, 'bulkDeleteTasks'])->int('board_id');
114 $router->get('/stage-task-available-positions/{stage_id}', [BoardController::class, 'getStageTaskAvailablePositions'])->int('board_id')->int('stage_id');
115
116 $router->post('/crm-contact', [BoardController::class, 'updateAssociateCrmContact'])->int('board_id');
117 $router->get('/crm-contacts', [BoardController::class, 'getAssociateCrmContacts'])->int('board_id');
118 $router->delete('/crm-contact/{contact_id}', [BoardController::class, 'deleteAssociateCrmContact'])->int('board_id')->int('contact_id');
119
120 $router->get('/notification-settings', [NotificationController::class, 'getBoardNotificationSettings'])->int('board_id');
121 $router->put('/update-notification-settings', [NotificationController::class, 'updateBoardNotificationSettings'])->int('board_id');
122
123 $router->post('/duplicate-board', [BoardController::class, 'duplicateBoard'])->int('board_id');
124 $router->post('/import-from-board', [BoardController::class, 'importFromBoard'])->int('board_id');
125
126 $router->put('/upload/background', [BoardController::class, 'setBoardBackground'])->int('board_id');
127 $router->post('/upload/background-image', [BoardController::class, 'uploadBoardBackground'])->int('board_id');
128 $router->put('/archive-board', [BoardController::class, 'archiveBoard'])->int('board_id');
129 $router->put('/restore-board', [BoardController::class, 'restoreBoard'])->int('board_id');
130 $router->get('/board-menu-items', [BoardController::class, 'getBoardMenuItems'])->int('board_id');
131 $router->get('/public-access-settings', [BoardController::class, 'getPublicAccessSettings'])->int('board_id');
132 $router->put('/toggle-public-access', [BoardController::class, 'togglePublicAccess'])->int('board_id');
133
134
135 //# Tasks under a single board routes
136 //# Route prefix: /projects/{id}/tasks
137 $router->prefix('/tasks')->group(function ($router) {
138 $router->get('/', [TaskController::class, 'getTasksByBoard'])->int('board_id');
139 $router->get('/filtered', [TaskController::class, 'getFilteredBoardTasks'])->int('board_id');
140 $router->get('/table', [TaskController::class, 'getTableTasks'])->int('board_id');
141 $router->get('/by-stage', [TaskController::class, 'getTasksByBoardStage'])->int('board_id');
142 $router->get('/stage-page', [TaskController::class, 'getStageTasksPage'])->int('board_id');
143 // 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.
144 $router->post('/', [TaskController::class, 'create']);
145 $router->post('/create-task-from-image', [TaskController::class, 'createTaskFromImage'])->int('board_id');
146 $router->get('/archived', [TaskController::class, 'getArchivedTasks'])->int('board_id');
147 $router->get('/{task_id}', [TaskController::class, 'find'])->int('board_id')->int('task_id')->int('task_id');
148 $router->put('/{task_id}', [TaskController::class, 'updateTaskProperties'])->int('board_id')->int('task_id');
149 $router->delete('/{task_id}/support-ticket', [TaskController::class, 'removeSupportTicketLink'])
150 ->int('board_id')
151 ->int('task_id');
152 $router->post('/{task_id}/dates', [TaskController::class, 'updateTaskDates'])->int('board_id')->int('task_id');
153 $router->put('/{task_id}/move-task', [TaskController::class, 'moveTask'])->int('board_id')->int('task_id');
154 $router->post('/bulk-actions', [TaskController::class, 'bulkActions'])->int('board_id');
155 $router->post('/update-cover-photo/{task_id}', [TaskController::class, 'updateTaskCoverPhoto'])->int('task_id');
156 $router->post('/status-update/{task_id}', [TaskController::class, 'taskStatusUpdate'])->int('task_id');
157 $router->delete('/{task_id}', [TaskController::class, 'deleteTask'])->int('board_id')->int('task_id');
158 $router->put('/{task_id}/move-to-next-stage', [TaskController::class, 'moveTaskToNextStage'])->int('board_id')->int('task_id');
159 $router->put('/{task_id}/pin', [TaskController::class, 'toggleTaskPinned'])->int('board_id')->int('task_id');
160
161 // AI task intelligence (summarize / subtasks / suggestions) — board-scoped.
162 $router->post('/{task_id}/ai-assist', [AiController::class, 'taskAssist'])->int('board_id')->int('task_id');
163 // Transactional batch apply for AI label/priority suggestions (all-or-nothing).
164 // Bulk subtask creation lives with the other subtask APIs in Fluent Boards Pro.
165 $router->post('/{task_id}/ai-apply-suggestions', [AiController::class, 'applySuggestions'])->int('board_id')->int('task_id');
166
167 // Comments Routes Area
168 $router->get('/{task_id}/comments', [CommentController::class, 'getComments'])->int('board_id')->int('task_id');
169 $router->post('/{task_id}/comments', [CommentController::class, 'create'])->int('board_id')->int('task_id');
170 $router->put('/comments/{comment_id}', [CommentController::class, 'update'])->int('board_id')->int('comment_id');
171 $router->put('/reply/{reply_id}', [CommentController::class, 'updateReply'])->int('board_id')->int('reply_id');
172 $router->delete('/comments/{comment_id}', [CommentController::class, 'deleteComment'])->int('board_id')->int('comment_id');
173 $router->delete('/reply/{reply_id}', [CommentController::class, 'deleteReply'])->int('board_id')->int('reply_id');
174 $router->put('/comments/{comment_id}/privacy', [CommentController::class, 'updateCommentPrivacy'])->int('board_id')->int('comment_id');
175
176
177 // Activities Area
178 $router->get('/{task_id}/activities', [TaskController::class, 'getActivities'])->int('board_id')->int('task_id');
179
180 $router->post('/{task_id}/assign-yourself', [TaskController::class, 'assignYourselfInTask'])->int('board_id')->int('task_id');
181 $router->post('/{task_id}/detach-yourself', [TaskController::class, 'detachYourselfFromTask'])->int('board_id')->int('task_id');
182 $router->get('/{task_id}/comments-and-activities', [TaskController::class, 'getCommentsAndActivities'])->int('board_id')->int('task_id');
183 $router->post('/{task_id}/comment-image-upload', [CommentController::class, 'handleImageUpload'])->int('board_id')->int('task_id');
184 $router->post('/{task_id}/task-cover-image-upload', [TaskController::class, 'handleTaskCoverImageUpload'])->int('board_id')->int('task_id');
185 $router->post('/{task_id}/remove-task-cover', [TaskController::class, 'removeTaskCover'])->int('board_id')->int('task_id');
186 $router->post('/{task_id}/wp-editor-media-file-upload', [TaskController::class, 'uploadMediaFileFromWpEditor'])->int('board_id')->int('task_id');
187 $router->post('/{task_id}/clone-task', [TaskController::class, 'cloneTask'])->int('board_id')->int('task_id');
188 });
189 });
190
191 $router->prefix('admin')->withPolicy('AdminPolicy')->group(function ($router) {
192
193 $router->get('/feature-modules', [OptionsController::class, 'getAddonsSettings']);
194 $router->post('/feature-modules', [OptionsController::class, 'saveAddonsSettings']);
195 $router->post('/feature-modules/install-plugin', [OptionsController::class, 'installPlugin']);
196
197 $router->get('/general-settings', [OptionsController::class, 'getGeneralSettings']);
198 $router->post('/general-settings', [OptionsController::class, 'saveGeneralSettings']);
199
200 $router->get('/mcp/status', [MCPSettingsController::class, 'status']);
201 $router->post('/mcp/toggle', [MCPSettingsController::class, 'toggle']);
202 $router->post('/mcp/install-adapter', [MCPSettingsController::class, 'installAdapter']);
203 $router->get('/mcp/config-snippet', [MCPSettingsController::class, 'getConfigSnippet']);
204
205 $router->get('pages', [OptionsController::class, 'getPages']);
206
207 $router->prefix('folders')->group(function ($router) {
208 $router->get('/', [FolderController::class, 'getFolders']);
209 $router->post('/', [FolderController::class, 'createFolder']);
210 $router->prefix('/{folder_id}')->group(function ($router) {
211 $router->get('/', [FolderController::class, 'getFolderById'])->int('folder_id');
212 $router->post('/add-board', [FolderController::class, 'addBoardToFolder'])->int('folder_id');
213 $router->post('/remove-board', [FolderController::class, 'removeBoardFromFolder'])->int('folder_id');
214 $router->put('/', [FolderController::class, 'updateFolder'])->int('folder_id');
215 $router->delete('/', [FolderController::class, 'deleteFolder'])->int('folder_id');
216 });
217 });
218
219 });
220
221 // AI writing assistant. Settings routes are admin-only; `generate` is open to
222 // any authenticated user (enforced per-method inside AiPolicy).
223 $router->prefix('ai')->withPolicy('AiPolicy')->group(function ($router) {
224 $router->get('/settings', [AiController::class, 'getSettings']);
225 $router->post('/settings', [AiController::class, 'saveSettings']);
226 $router->post('/models', [AiController::class, 'getModels']);
227 $router->post('/test', [AiController::class, 'testConnection']);
228 $router->post('/generate', [AiController::class, 'generate']);
229 });
230
231 $router->prefix('webhooks')->withPolicy('WebhookPolicy')->group(function ($router) {
232 $router->get('/', [WebhookController::class, 'index']);
233 $router->post('/', [WebhookController::class, 'create']);
234 $router->put('/{id}', [WebhookController::class, 'update'])->int('id');
235 $router->delete('/{id}', [WebhookController::class, 'delete'])->int('id');
236 });
237
238 // Add outgoing webhook routes
239 $router->prefix('outgoing-webhooks')->withPolicy('WebhookPolicy')->group(function ($router) {
240 $router->get('/', [WebhookController::class, 'outgoingWebhooks']);
241 $router->post('/', [WebhookController::class, 'createOutgoingWebhook']);
242 $router->put('/{id}', [WebhookController::class, 'updateOutgoingWebhook'])->int('id');
243 $router->delete('/{id}', [WebhookController::class, 'deleteOutgoingWebhook'])->int('id');
244 });
245
246
247 $router->prefix('member/{id}')->withPolicy('UserPolicy')->group(function ($router) {
248 $router->get('/', [UserController::class, 'getMemberInfo']);
249 $router->get('/projects', [UserController::class, 'getMemberBoards']);
250 $router->get('/tasks', [UserController::class, 'getMemberAssociatedTasks']);
251 $router->get('/task-counts', [UserController::class, 'getMemberTaskCounts']);
252 $router->get('/activities', [UserController::class, 'getMemberRelatedAcitivies']);
253 $router->get('/stats', [UserController::class, 'getMemberStats']);
254 });
255
256 /*
257 * TODO: I guess we can minimize the number of routes. and Backend code needs to be refactored
258 */
259
260 // Notification routes
261 $router->prefix('notifications')->withPolicy('UserPolicy')->group(function ($router) {
262 $router->get('/', [NotificationController::class, 'getAllNotifications']);
263 $router->get('/unread', [NotificationController::class, 'getAllUnreadNotifications']);
264 $router->get('/unread-count', [NotificationController::class, 'newNotificationNumber']);
265 $router->put('/read', [NotificationController::class, 'readNotification']);
266 });
267
268 $router->prefix('contacts/{board_id}')->withPolicy('SingleBoardPolicy')->group(function ($router) {
269 $router->get('/', [TaskController::class, 'getAssociatedCrmContacts'])->int('board_id');
270 });
271
272 $router->prefix('public/boards/{board_id}')->withPolicy('PublicBoardPolicy')->group(function ($router) {
273 $router->get('/', [PublicBoardController::class, 'find'])->int('board_id');
274 $router->get('/tasks', [PublicBoardController::class, 'getTasksByBoard'])->int('board_id');
275 $router->get('/tasks/by-stage', [PublicBoardController::class, 'getTasksByBoardStage'])->int('board_id');
276 $router->get('/tasks/stage-page', [PublicBoardController::class, 'getStageTasksPage'])->int('board_id');
277 });
278
279 // User utility routes
280 $router->withPolicy('UserPolicy')->group(function ($router) {
281 $router->get('/global-search', [OptionsController::class, 'globalSearch']);
282 });
283
284
285 $router->prefix('options')->withPolicy('AuthPolicy')->group(function ($router) {
286 $router->get('members', [OptionsController::class, 'getBoardMembers']);
287 $router->get('projects', [OptionsController::class, 'getBoards']);
288 });
289