Skip to content

Latest commit

 

History

History
366 lines (316 loc) · 7.54 KB

File metadata and controls

366 lines (316 loc) · 7.54 KB

Notes API Quick Reference

Endpoints

All endpoints require authentication via Bearer token in the Authorization header.

1. Create or Update Note

POST /api/v1/user/notes

Creates a new note or replaces the user's existing active note.

Request Body:

{
  "text": "at the gym 💪",
  "audience": "followers"  // or "everyone"
}

Response (201 Created):

{
  "status": 201,
  "message": "Note created successfully",
  "data": {
    "note": {
      "_id": "...",
      "author": {
        "_id": "...",
        "userName": "john",
        "displayName": "John Doe",
        "profileImage": "/images/...",
        "school": "Arcadia High School"
      },
      "text": "at the gym 💪",
      "audience": "followers",
      "expiresAt": "2025-11-26T12:00:00.000Z",
      "createdAt": "2025-11-25T12:00:00.000Z"
    }
  }
}

Validation:

  • Text is required and must be 1-60 characters
  • Audience must be "followers" or "everyone"
  • Only one active note per user (previous note is deleted)

2. Get Note Feed

GET /api/v1/user/notes/feed?audience=followers

Retrieves notes based on the selected audience filter.

Query Parameters:

  • audience (optional): "followers" (default) or "everyone"

Response (200 OK):

{
  "status": 200,
  "message": "Notes fetched successfully",
  "data": {
    "notes": [
      {
        "_id": "...",
        "author": {
          "_id": "...",
          "userName": "sarah",
          "displayName": "Sarah Johnson",
          "profileImage": "/images/...",
          "school": "Arcadia High School"
        },
        "text": "studying for finals 📚",
        "audience": "followers",
        "expiresAt": "2025-11-26T14:30:00.000Z",
        "createdAt": "2025-11-25T14:30:00.000Z"
      }
    ]
  }
}

Feed Logic:

  • audience=followers: Returns notes from users you follow + your own note
  • audience=everyone: Returns all public notes (audience="everyone")
  • Results sorted by createdAt descending (newest first)
  • Limit: 100 notes

3. Get Own Active Note

GET /api/v1/user/notes/mine

Retrieves the current user's active note (if any).

Response (200 OK):

{
  "status": 200,
  "message": "Note fetched successfully",
  "data": {
    "note": {
      "_id": "...",
      "author": { ... },
      "text": "at the gym 💪",
      "audience": "followers",
      "expiresAt": "2025-11-26T12:00:00.000Z",
      "createdAt": "2025-11-25T12:00:00.000Z"
    }
  }
}

If no active note:

{
  "status": 200,
  "message": "No active note",
  "data": {
    "note": null
  }
}

4. Delete Note

DELETE /api/v1/user/notes

Deletes the user's active note.

Response (200 OK):

{
  "status": 200,
  "message": "Note deleted successfully",
  "data": {}
}

If no active note (404):

{
  "status": 404,
  "message": "No active note to delete",
  "data": {}
}

Testing with cURL

Create a note:

curl -X POST https://api.theirlapp.com/api/v1/user/notes \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Testing notes feature 🎉",
    "audience": "followers"
  }'

Get followers feed:

curl -X GET "https://api.theirlapp.com/api/v1/user/notes/feed?audience=followers" \
  -H "Authorization: Bearer YOUR_TOKEN"

Get everyone feed:

curl -X GET "https://api.theirlapp.com/api/v1/user/notes/feed?audience=everyone" \
  -H "Authorization: Bearer YOUR_TOKEN"

Get own note:

curl -X GET https://api.theirlapp.com/api/v1/user/notes/mine \
  -H "Authorization: Bearer YOUR_TOKEN"

Delete note:

curl -X DELETE https://api.theirlapp.com/api/v1/user/notes \
  -H "Authorization: Bearer YOUR_TOKEN"

Error Codes

  • 400 Bad Request: Invalid input (missing text, invalid audience, text too long)
  • 401 Unauthorized: Missing or invalid token
  • 404 Not Found: No active note to delete
  • 500 Internal Server Error: Server error

MongoDB TTL Index

Notes automatically expire after 24 hours via MongoDB's TTL index on the expiresAt field. MongoDB's background task checks for expired documents approximately every 60 seconds.

To verify TTL index:

db.notes.getIndexes()
// Should show: { expiresAt: 1 } with expireAfterSeconds: 0

To manually test expiry (for development):

// Create a note that expires in 1 minute
db.notes.insertOne({
  author: ObjectId("..."),
  text: "Test expiry",
  audience: "followers",
  expiresAt: new Date(Date.now() + 60000), // 1 minute
  createdAt: new Date()
})

// Wait 2 minutes, then check
db.notes.find({ text: "Test expiry" })
// Should return empty

Postman Collection

Import the following into Postman:

{
  "info": {
    "name": "IRL Notes API",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "name": "Create Note",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Authorization",
            "value": "Bearer {{token}}"
          }
        ],
        "body": {
          "mode": "raw",
          "raw": "{\n  \"text\": \"Testing notes 🎉\",\n  \"audience\": \"followers\"\n}",
          "options": {
            "raw": {
              "language": "json"
            }
          }
        },
        "url": {
          "raw": "{{baseUrl}}/api/v1/user/notes",
          "host": ["{{baseUrl}}"],
          "path": ["api", "v1", "user", "notes"]
        }
      }
    },
    {
      "name": "Get Feed (Followers)",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Authorization",
            "value": "Bearer {{token}}"
          }
        ],
        "url": {
          "raw": "{{baseUrl}}/api/v1/user/notes/feed?audience=followers",
          "host": ["{{baseUrl}}"],
          "path": ["api", "v1", "user", "notes", "feed"],
          "query": [
            {
              "key": "audience",
              "value": "followers"
            }
          ]
        }
      }
    },
    {
      "name": "Get Feed (Everyone)",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Authorization",
            "value": "Bearer {{token}}"
          }
        ],
        "url": {
          "raw": "{{baseUrl}}/api/v1/user/notes/feed?audience=everyone",
          "host": ["{{baseUrl}}"],
          "path": ["api", "v1", "user", "notes", "feed"],
          "query": [
            {
              "key": "audience",
              "value": "everyone"
            }
          ]
        }
      }
    },
    {
      "name": "Get Own Note",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Authorization",
            "value": "Bearer {{token}}"
          }
        ],
        "url": {
          "raw": "{{baseUrl}}/api/v1/user/notes/mine",
          "host": ["{{baseUrl}}"],
          "path": ["api", "v1", "user", "notes", "mine"]
        }
      }
    },
    {
      "name": "Delete Note",
      "request": {
        "method": "DELETE",
        "header": [
          {
            "key": "Authorization",
            "value": "Bearer {{token}}"
          }
        ],
        "url": {
          "raw": "{{baseUrl}}/api/v1/user/notes",
          "host": ["{{baseUrl}}"],
          "path": ["api", "v1", "user", "notes"]
        }
      }
    }
  ],
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://api.theirlapp.com"
    },
    {
      "key": "token",
      "value": "YOUR_TOKEN_HERE"
    }
  ]
}