You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .claude/skills/general-practices/backend-endpoints/SKILL.md
+54-93Lines changed: 54 additions & 93 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,11 +1,6 @@
1
1
---
2
2
name: backend-endpoints
3
-
description: >-
4
-
Guide for creating backend API endpoints in FinishLine following the
5
-
Route → Controller → Service pattern with multi-tenant security.
6
-
Use when creating new endpoints, adding API routes, implementing
7
-
controllers or services, building backend request handlers, or
8
-
when asked how the backend works.
3
+
description: Guide for creating backend API endpoints in FinishLine following the Route → Controller → Service pattern with multi-tenant security. Use when creating new endpoints, adding API routes, implementing controllers or services, building backend request handlers, or when asked how the backend works.
9
4
---
10
5
11
6
# Backend Endpoints
@@ -63,15 +58,15 @@ If a service throws an exception, it bubbles up through the controller's `next(e
| Express types |`src/backend/custom.d.ts`|`currentUser` and `organization` on `Request`|
75
70
76
71
For query args and transformers, see the [query-args-and-transformers](../query-args-and-transformers/SKILL.md) skill.
77
72
@@ -80,11 +75,13 @@ For query args and transformers, see the [query-args-and-transformers](../query-
80
75
The full URL path for any endpoint is the **combination** of the base path registered in `src/backend/index.ts` and the route path in the router file. This is a very common source of confusion.
81
76
82
77
For example, if `index.ts` registers:
78
+
83
79
```typescript
84
80
app.use('/calendar', calendarRouter);
85
81
```
86
82
87
83
And the router defines:
84
+
88
85
```typescript
89
86
calendarRouter.post('/shop/create', ...);
90
87
```
@@ -103,13 +100,8 @@ Add validation rules using `express-validator` and the helpers from `validation.
- URL params use `param()`, query strings use `query()`, body fields use `body()`.
136
128
137
129
**When to abstract validators:** Keep validation inline in the route by default. Only extract validators into `validation.utils.ts` when:
130
+
138
131
- The request body contains a **nested object** that is itself a known entity (e.g., a work package embedded inside a project create payload). Create a named validator array like `workPackageProposedChangesValidators`.
139
132
- The **same set of validations** is repeated across multiple routes (e.g., `descriptionBulletsValidators` used in both work package and project routes).
140
133
@@ -146,8 +139,7 @@ If creating a brand new feature router, register it in `src/backend/index.ts`:
|`InvalidOrganizationException(item)`| 400 | Entity not in current org|
364
325
365
326
The `name` parameter for `NotFoundException` and `DeletedException` MUST be one of the values in the `ExceptionObjectNames` type union in `errors.utils.ts`. Add your entity to that type if it's not listed.
0 commit comments