A robust Node.js backend API for the Memora flashcard application - a web-based memory training tool that helps users create, manage, and study flashcards.
🌐 Live at: memora.tiberiusgh.com
- User Management: Firebase Authentication integration with MongoDB for persistent user profiles
- Flashcard Collections: Create, update, delete, and manage flashcard collections
- Individual Flashcards: Full CRUD operations for flashcards within collections
- Public Collections: Share collections publicly and browse community content
- Access Control: Role-based permissions for collections and flashcards
- Comprehensive Logging: Winston-based logging with multiple transports
- Request Tracking: UUID-based request tracking and HTTP context management
- Security: Helmet.js security headers, XSS protection, and input sanitization
- Express.js: Web framework
- MongoDB: Database with Mongoose ODM
- Firebase Admin SDK: Authentication and user management
- Winston: Structured logging
- Morgan: HTTP request logging
- Node.js
- MongoDB
- Firebase project with Admin SDK credentials
-
Clone the repository
git clone https://github.com/Memora-Tiberiusgh/backend cd backend -
Install dependencies
npm install
-
Environment Configuration
Copy the provided
example.envfile to.envand configure with your values:cp example.env .env
Then edit the
.envfile with your specific configuration values. -
Start the development server
npm run dev
The application can be containerized for both development and production environments. The easiest way to run the complete Memora stack (backend, frontend, and database) is through the docker-compose file provided in the orchestrator repository:
Using Docker Compose (Recommended):
# Clone the orchestrator repository
git clone https://github.com/Memora-Tiberiusgh/orchestrator
cd orchestrator
# Follow the setup instructions in the orchestrator README
# This will start the entire Memora application stackManual Docker Build (if needed):
Development Environment:
docker build -f Dockerfile.dev -t memora-backend:dev .
docker run -p 8186:8186 memora-backend:devProduction Environment:
docker build -f Dockerfile -t memora-backend:prod .
docker run -p 8186:8186 memora-backend:prodAll protected routes require Firebase ID token in the Authorization header:
Authorization: Bearer <firebase-id-token>
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /users |
Create/retrieve user profile | No |
| PUT | /users/collections/:collectionId |
Toggle collection in user library | Yes |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /collections |
Get user's collections | Yes |
| POST | /collections |
Create new collection | Yes |
| GET | /collections/public |
Get public collections | Yes |
| GET | /collections/:collectionId |
Get specific collection | Yes |
| PATCH | /collections/:collectionId |
Update collection | Yes |
| DELETE | /collections/:collectionId |
Delete collection | Yes |
| POST | /collections/:collectionId/submit |
Submit for public review | Yes |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /flashcards |
Create new flashcard | Yes |
| GET | /flashcards/:flashcardId |
Get specific flashcard | Yes |
| PATCH | /flashcards/:flashcardId |
Update flashcard | Yes |
| DELETE | /flashcards/:flashcardId |
Delete flashcard | Yes |
| GET | /flashcards/collections/:collectionId |
Get collection's flashcards | Yes |
Create Collection:
POST /collections
{
"name": "Spanish Vocabulary",
"description": "Basic Spanish words and phrases"
}Create Flashcard:
POST /flashcards
{
"question": "¿Cómo estás?",
"answer": "How are you?",
"collectionId": "64f7b1234567890abcdef123"
}- Input Sanitization: XSS protection using the
xsslibrary - Authentication: Firebase ID token verification
- Authorization: Role-based access control for collections and flashcards
- Security Headers: Helmet.js for security headers
- Error Handling: Sanitized error responses in production
- Request Tracking: UUID-based request correlation
The application uses Winston for comprehensive logging with multiple transports:
- Console: Formated logs for development
- File Logging: Separate files for combined, error, and exception logs
- MongoDB: Optional database logging for warnings and errors
- Submission Tracking: Dedicated logging for collection submissions
{
firebaseUid: String, // Firebase UID (unique)
displayName: String, // User display name
email: String, // User email
userAddedCollections: [ObjectId] // References to added collections
}{
name: String, // Collection name (1-50 characters)
description: String, // Optional description (max 500 characters)
isPublic: Boolean, // Public visibility flag
creator: ObjectId, // Reference to User
submitted: Boolean // Submission status for review
}{
question: String, // Question text (1-500 characters)
answer: String, // Answer text (1-1000 characters)
collectionId: ObjectId, // Reference to Collection
creator: ObjectId // Reference to User
}This project uses ESLint with LNU configuration for consistent code formatting.
- Fork the repository
- Create a feature branch:
git checkout -b feature/new-feature - Make your changes
- Run tests and linting:
npm run lint - Commit your changes:
git commit -am 'Add new feature' - Push to the branch:
git push origin feature/new-feature - Submit a pull request
This project is licensed under the MIT License.
For issues and feature requests, please visit our GitHub Discussions or contribute to the project at GitHub organization.
Tiberius Gherac - tiberius.gherac@gmail.com
First-year Web Development Student @ Linnaeus University
GitHub: @TiberiusGh