Skip to content

Commit 47eee07

Browse files
committed
feat: updated cluade md and existing crud operations
1 parent 7c34afa commit 47eee07

7 files changed

Lines changed: 368 additions & 58 deletions

File tree

CLAUDE.md

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,26 @@ Entry point: `src/server.js:1`
99
## Tech Stack
1010

1111
**Runtime & Framework:**
12+
1213
- Node.js with Express 4.18.2
1314
- ES2021 JavaScript with ES modules
1415

1516
**Core Dependencies:**
17+
1618
- `express` - REST API framework
1719
- `cors` - CORS middleware
1820
- `dotenv` - Environment configuration
1921
- `uuid` - ID generation
2022

2123
**Development:**
24+
2225
- `jest` + `supertest` - Testing with coverage
2326
- `eslint` - Code linting
2427
- `nodemon` - Auto-reload
2528
- `husky` + `lint-staged` - Git hooks
2629

2730
**Data Storage:**
31+
2832
- In-memory Map-based storage (database-replaceable design)
2933

3034
## Project Structure
@@ -57,12 +61,14 @@ openapi/
5761
## Essential Commands
5862

5963
**Development:**
64+
6065
```bash
6166
npm run dev # Start with auto-reload
6267
npm start # Production start
6368
```
6469

6570
**Testing:**
71+
6672
```bash
6773
npm test # Run all tests with coverage
6874
npm run test:unit # Unit tests only
@@ -71,12 +77,14 @@ npm run test:watch # Watch mode
7177
```
7278

7379
**Code Quality:**
80+
7481
```bash
7582
npm run lint # Check code style
7683
npm run lint:fix # Auto-fix issues
7784
```
7885

7986
**Environment Setup:**
87+
8088
```bash
8189
cp .env.example .env # Create environment file
8290
# Configure PORT (default 3000)
@@ -109,6 +117,7 @@ This codebase follows a layered REST architecture with middleware composition. K
109117
**Error:** `{ error: { name, message } }`
110118

111119
HTTP Status Codes:
120+
112121
- `200` - Success
113122
- `400` - Validation error
114123
- `401` - Authentication required
@@ -123,10 +132,211 @@ For deeper technical details, see:
123132

124133
- `.claude/docs/architectural_patterns.md` - Design patterns, conventions, and architectural decisions used throughout the codebase
125134

135+
## Postman Collection Management
136+
137+
**IMPORTANT:** Whenever API endpoints are added, modified, or deleted, the Postman collection MUST be updated to maintain synchronization between implementation and documentation.
138+
139+
### When to Update Collections
140+
141+
After implementing endpoint changes, **ALWAYS ask the user** if they want to update the Postman collection before proceeding. Never update automatically without confirmation.
142+
143+
Example prompt:
144+
145+
```
146+
I've completed the endpoint implementation. Would you like me to update the Postman collection
147+
to reflect these changes?
148+
```
149+
150+
### Collection Update Workflow
151+
152+
Follow this exact workflow when updating Postman collections:
153+
154+
**Step 1: Get Workspace Information**
155+
156+
- Ask user for workspace name (not ID initially)
157+
- Use `mcp__postman__getWorkspaces` to search for workspaces
158+
- Display matching workspaces and ask user to confirm the correct one
159+
- If workspace name provided doesn't match, ask for clarification
160+
161+
**Step 2: Get Collection Information**
162+
163+
- Once workspace is confirmed, use `mcp__postman__getCollections` with the workspace ID
164+
- Display available collections in that workspace
165+
- Ask user to confirm which collection to update
166+
- If collection name is ambiguous, show details and ask for confirmation
167+
168+
**Step 3: Read and Validate Current Collection**
169+
170+
- Use `mcp__postman__getCollection` with `model: "full"` parameter to retrieve complete collection data
171+
- Review current structure, requests, and organization
172+
- Identify which requests need to be added, updated, or removed
173+
- Validate against the API implementation (check routes in `src/routes/` directory)
174+
175+
**Step 4: Prepare Updated Collection**
176+
177+
- Start with current collection structure
178+
- **CRITICAL: Flatten all folders** - Extract all requests from nested folders to root level
179+
- Remove all `item` entries that are folders (only keep request items)
180+
- Update/add/remove requests as needed
181+
- Ensure each request includes:
182+
- Correct HTTP method
183+
- Full URL with path parameters
184+
- Request headers (including `x-api-key` for auth)
185+
- Request body with examples
186+
- Response examples
187+
- Maintain collection-level auth, variables, and scripts
188+
189+
**Step 5: Update Collection**
190+
191+
- **NEVER use `mcp__postman__updateCollectionRequest`** - it is too limited
192+
- **ALWAYS use `mcp__postman__putCollection`** instead
193+
- Pass the complete collection object with all required fields
194+
- Include collection ID in the request
195+
- Ensure `info` object has required `name` and `schema` properties
196+
197+
**Step 6: Verify Update**
198+
199+
- Read the collection again using `mcp__postman__getCollection`
200+
- Confirm changes were applied correctly
201+
- Report success to user with summary of changes
202+
203+
### Critical Rules for Collection Updates
204+
205+
1. **No Folders Allowed**
206+
207+
- Collections MUST be flat (no nested folders or item groups)
208+
- If reading a collection with folders, automatically flatten it
209+
- Extract all requests from folders and place at root `item` array
210+
- Do not warn user - just flatten automatically
211+
212+
2. **Always Use putCollection**
213+
214+
- `mcp__postman__updateCollectionRequest` cannot update: request body, URL, auth, headers, method
215+
- It's essentially useless for real updates
216+
- Always use `mcp__postman__putCollection` for ANY collection modification
217+
218+
3. **Preserve Collection IDs**
219+
220+
- When updating, retain all existing IDs: `id`, `uid`, `_postman_id`
221+
- If IDs are missing, the API will generate new ones (breaking references)
222+
- Read collection first to get current IDs, then update with same IDs
223+
224+
4. **Collection Format Requirements**
225+
226+
```javascript
227+
{
228+
collection: {
229+
info: {
230+
name: "Collection Name",
231+
schema: "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
232+
description: "Optional description"
233+
},
234+
item: [
235+
// Array of request objects ONLY (no folders)
236+
{
237+
name: "Request Name",
238+
request: {
239+
method: "GET|POST|PUT|DELETE",
240+
header: [...],
241+
url: {...},
242+
body: {...} // for POST/PUT
243+
},
244+
response: []
245+
}
246+
],
247+
auth: {...}, // Optional collection-level auth
248+
variable: [...], // Optional collection variables
249+
event: [...] // Optional pre-request/test scripts
250+
}
251+
}
252+
```
253+
254+
5. **Request Structure**
255+
Each request must include:
256+
257+
- `name` - Clear, descriptive name
258+
- `request.method` - HTTP method
259+
- `request.url` - Can be string or object with `raw`, `host`, `path`, `query`
260+
- `request.header` - Array of header objects with `key`, `value`
261+
- `request.body` (for POST/PUT) - Object with `mode` and content
262+
- `response` - Array of example responses (can be empty)
263+
264+
6. **Authentication**
265+
266+
- Set collection-level auth if all requests use same auth
267+
- For this API: use `apikey` type with `x-api-key` header
268+
- Individual requests can override collection auth
269+
270+
7. **Variables**
271+
- Use collection variables for: `baseUrl`, `apiKey`
272+
- Format: `{ key: "varName", value: "default value", type: "string" }`
273+
274+
### Example Postman Update Flow
275+
276+
```
277+
User: "Update the Postman collection with the new endpoints"
278+
279+
Assistant: "Which workspace should I update? Please provide the workspace name."
280+
281+
User: "My Team Workspace"
282+
283+
Assistant:
284+
1. Call mcp__postman__getWorkspaces
285+
2. Search results for matching name
286+
3. Confirm: "Found workspace: My Team Workspace (ID: abc123). Is this correct?"
287+
288+
User: "Yes"
289+
290+
Assistant:
291+
4. Call mcp__postman__getCollections with workspace ID
292+
5. Display: "Found these collections: 1) Banking API Collection, 2) Test Collection"
293+
6. Ask: "Which collection should I update?"
294+
295+
User: "Banking API Collection"
296+
297+
Assistant:
298+
7. Call mcp__postman__getCollection with model: "full"
299+
8. Review collection structure and identify folders
300+
9. Flatten folders - extract all requests to root level
301+
10. Read src/routes/accounts.js to see implemented endpoints
302+
11. Add new GET /accounts/:id, PUT /accounts/:id, DELETE /accounts/:id requests
303+
12. Update existing GET /accounts and POST /accounts requests if needed
304+
13. Call mcp__postman__putCollection with updated collection
305+
14. Verify by reading collection again
306+
15. Report: "Collection updated successfully. Added 3 new endpoints, updated 2 existing endpoints."
307+
```
308+
309+
### Common Pitfalls to Avoid
310+
311+
- **DO NOT** use updateCollectionRequest - always use putCollection
312+
- **DO NOT** leave folders in collection - always flatten
313+
- **DO NOT** forget to preserve IDs when updating
314+
- **DO NOT** skip reading collection before updating
315+
- **DO NOT** forget to validate against actual routes in codebase
316+
- **DO NOT** update collection without asking user first
317+
- **DO NOT** guess workspace/collection IDs - always search and confirm
318+
319+
### Validation Checklist
320+
321+
Before calling putCollection, verify:
322+
323+
- [ ] All folders flattened (item array contains only requests, no folders)
324+
- [ ] All IDs preserved from original collection
325+
- [ ] All new endpoints from codebase included
326+
- [ ] Request URLs match route definitions in src/routes/
327+
- [ ] HTTP methods correct (GET/POST/PUT/DELETE)
328+
- [ ] Request bodies included for POST/PUT requests
329+
- [ ] x-api-key header included in all requests
330+
- [ ] Collection-level auth configured
331+
- [ ] Variables defined (baseUrl, apiKey)
332+
- [ ] info.name and info.schema present
333+
126334
## Development Notes
127335

128336
- Pre-commit hooks enforce linting and tests
129337
- All routes require authentication except admin key generation
130338
- Database uses singleton pattern with in-memory storage
131339
- Models implement `validate()`, `toJSON()`, and domain-specific methods
132340
- Error handling is centralized in middleware/errorHandler.js:7
341+
- Account ownership is tracked via API key - users can only access their own accounts
342+
- Soft delete is used for accounts (deleted flag) to preserve transaction history
File renamed without changes.
File renamed without changes.
File renamed without changes.

src/database/db.js

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ class Database {
2222
* Initialize with sample data for testing
2323
*/
2424
initializeSampleData() {
25-
// Create sample accounts
26-
const account1 = new Account('1', 'Nova Newman', 10000, 'COSMIC_COINS', '2023-04-10');
27-
const account2 = new Account('2', 'Gary Galaxy', 237, 'COSMIC_COINS', '2023-04-10');
28-
const account3 = new Account('3', 'Luna Starlight', 5000, 'GALAXY_GOLD', '2024-01-10');
29-
25+
// Create sample accounts (owned by default API key '1234')
26+
const account1 = new Account('1', 'Nova Newman', 10000, 'COSMIC_COINS', '2023-04-10', 'STANDARD', '1234', false);
27+
const account2 = new Account('2', 'Gary Galaxy', 237, 'COSMIC_COINS', '2023-04-10', 'PREMIUM', '1234', false);
28+
const account3 = new Account('3', 'Luna Starlight', 5000, 'GALAXY_GOLD', '2024-01-10', 'BUSINESS', '1234', false);
29+
3030
this.accounts.set('1', account1);
3131
this.accounts.set('2', account2);
3232
this.accounts.set('3', account3);
@@ -40,12 +40,20 @@ class Database {
4040

4141
/**
4242
* Get all accounts with optional filters
43-
* @param {Object} filters - Optional filters (owner, createdAt)
43+
* @param {Object} filters - Optional filters (owner, createdAt, apiKey)
4444
* @returns {Array<Account>}
4545
*/
4646
getAccounts(filters = {}) {
4747
let accounts = Array.from(this.accounts.values());
4848

49+
// Exclude deleted accounts
50+
accounts = accounts.filter(acc => !acc.deleted);
51+
52+
// Filter by API key for ownership
53+
if (filters.apiKey) {
54+
accounts = accounts.filter(acc => acc.apiKey === filters.apiKey);
55+
}
56+
4957
if (filters.owner) {
5058
accounts = accounts.filter(acc => acc.owner.toLowerCase().includes(filters.owner.toLowerCase()));
5159
}
@@ -69,16 +77,20 @@ class Database {
6977
/**
7078
* Create new account
7179
* @param {Object} accountData
80+
* @param {string} apiKey - API key of the creator
7281
* @returns {Account}
7382
*/
74-
createAccount(accountData) {
83+
createAccount(accountData, apiKey) {
7584
const accountId = uuidv4().split('-')[0]; // Generate short UUID
7685
const account = new Account(
7786
accountId,
7887
accountData.owner,
7988
accountData.balance || 0,
8089
accountData.currency,
81-
new Date().toISOString().split('T')[0]
90+
new Date().toISOString().split('T')[0],
91+
accountData.accountType || 'STANDARD',
92+
apiKey,
93+
false
8294
);
8395
this.accounts.set(accountId, account);
8496
console.log(`✓ Account created: ${accountId} - Total accounts: ${this.accounts.size}`);
@@ -93,24 +105,34 @@ class Database {
93105
*/
94106
updateAccount(accountId, updates) {
95107
const account = this.accounts.get(accountId);
96-
if (!account) {
108+
if (!account || account.deleted) {
97109
return null;
98110
}
99111

100112
if (updates.owner) {
101113
account.owner = updates.owner;
102114
}
103115

116+
if (updates.accountType) {
117+
account.accountType = updates.accountType;
118+
}
119+
104120
return account;
105121
}
106122

107123
/**
108-
* Delete account
124+
* Delete account (soft delete)
109125
* @param {string} accountId
110126
* @returns {boolean}
111127
*/
112128
deleteAccount(accountId) {
113-
return this.accounts.delete(accountId);
129+
const account = this.accounts.get(accountId);
130+
if (!account || account.deleted) {
131+
return false;
132+
}
133+
account.deleted = true;
134+
console.log(`✓ Account soft deleted: ${accountId}`);
135+
return true;
114136
}
115137

116138
// ============ Transaction Operations ============

0 commit comments

Comments
 (0)