Skip to content

japalacio-08/NotesTakingApp

Repository files navigation

Notes Taking App

A full-stack note-taking application with rich text editing, categories, and real-time syncing.

Tech Stack

Layer Technology
Backend Django 6.0, Django REST Framework, PostgreSQL 16
Frontend Next.js 14+, TypeScript, Tailwind CSS, Framer Motion
State Zustand (client), JWT authentication
Editor TipTap (ProseMirror-based rich text editor)
Container Docker, Docker Compose
Email Mailcatcher (development)

Features

  • Rich Text Editor: Bold, italic, headings, lists, links, images
  • Categories: Organize notes with colored categories
  • Real-time Sync: Differential patching for efficient updates
  • Speech-to-Text: Voice input support for note creation
  • Infinite Scroll: Lazy loading for large note collections
  • Authentication: JWT with automatic token refresh
  • Email Verification: Secure user registration flow

Quick Start

Prerequisites

  • Docker and Docker Compose
  • Make (optional but recommended)

Setup

# Clone and start
git clone <repository-url>
cd NotesTakingApp
make setup

Access Points

Service URL
Frontend http://localhost:3000
Backend API http://localhost:8000/api/v1
API Documentation http://localhost:8000/api/docs
Mailcatcher http://localhost:1080

Create Admin User

make createsuperuser

Development Commands

# Services
make build          # Build containers
make up              # Start all services
make down            # Stop all services
make restart         # Restart all services
make logs            # View all logs
make logs-backend    # View backend logs
make logs-frontend   # View frontend logs

# Database
make migrate         # Run migrations
make makemigrations  # Create new migrations
make reset-db        # Reset database (destructive!)

# Shell Access
make shell-backend   # Django shell
make shell-frontend  # Frontend container shell

# Cleanup
make clean           # Remove containers and volumes

API Documentation

Interactive Documentation

Visit http://localhost:8000/api/docs for Swagger UI documentation.

Response Format

Success Response:

{
  "success": true,
  "data": { ... },
  "meta": {
    "pagination": {
      "page": 1,
      "page_size": 10,
      "total_pages": 5,
      "total_count": 50,
      "has_next": true,
      "has_previous": false
    }
  }
}

Error Response:

{
  "errors": [
    {
      "code": "validation_error",
      "message": "This field is required.",
      "field": "email"
    }
  ]
}

Key Endpoints

Endpoint Methods Description
/auth/login/ POST Authenticate user
/auth/register/ POST Register new user
/auth/refresh/ POST Refresh access token
/notes/ GET, POST List/create notes
/notes/{id}/ GET, PATCH, DELETE Note operations
/notes/{id}/patch_content/ POST Differential update
/categories/ GET, POST List/create categories

Project Structure

NotesTakingApp/
├── backend/               # Django REST API
│   ├── config/            # Settings, URLs
│   ├── core/              # Shared utilities
│   ├── users/             # Authentication
│   ├── notes/             # Notes & categories
│   └── README.md          # Backend architecture
├── frontend/              # Next.js application
│   ├── src/
│   │   ├── app/           # Pages & layouts
│   │   ├── components/    # UI components
│   │   ├── hooks/         # Custom hooks
│   │   ├── store/         # Zustand stores
│   │   └── lib/           # Utilities
│   └── README.md          # Frontend architecture
├── .cursor/rules/         # Cursor IDE rules
├── docker-compose.yml
├── Makefile
└── README.md

Environment Variables

Backend (.env)

DEBUG=True
SECRET_KEY=your-secret-key-here
ALLOWED_HOSTS=localhost,127.0.0.1

# Database
POSTGRES_DB=notes_db
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_HOST=postgres
POSTGRES_PORT=5432

# Email (Mailcatcher for development)
EMAIL_HOST=mailcatcher
EMAIL_PORT=1025

# CORS
FRONTEND_URL=http://localhost:3000
CORS_ALLOWED_ORIGINS=http://localhost:3000

Frontend (.env.local)

NEXT_PUBLIC_API_URL=http://localhost:8000/api/v1

Architecture Documentation

  • Backend: See backend/README.md for Django architecture details
  • Frontend: See frontend/README.md for Next.js architecture details
  • AI Guidelines: See AGENTS.md and .cursor/rules/ for development patterns

Development Process Summary

Overview

This Notes Taking Application was built following a modern full-stack architecture with a clear separation of concerns between the Django REST API backend and the Next.js frontend. The development process followed an iterative approach, starting with core functionality and progressively adding features.

Development Phases

  1. Project Setup & Infrastructure

    • Docker Compose configuration for development environment
    • PostgreSQL database with Django ORM
    • Next.js with TypeScript and Tailwind CSS
    • Makefile for common development tasks
  2. Backend API Development

    • RESTful API design with Django REST Framework
    • JWT authentication with SimpleJWT
    • Custom exception handling with standardized error responses
    • Swagger/OpenAPI documentation with drf-spectacular
  3. Frontend Development

    • Component-based architecture with React/Next.js
    • State management with Zustand stores
    • Rich text editing with TipTap (ProseMirror)
    • Responsive design with Tailwind CSS and Framer Motion animations
  4. Testing & Quality Assurance

    • Backend: pytest with pytest-django, factory-boy for test data
    • Frontend: Jest with React Testing Library
    • Coverage reporting for both backend and frontend

Key Design & Technical Decisions

1. Differential Patching (diff-match-patch)

Decision: Use diff-match-patch algorithm for note content synchronization instead of sending full content on each save.

Rationale:

  • Reduces bandwidth by only sending changes (deltas)
  • Enables conflict resolution in collaborative scenarios
  • More efficient for large notes with small edits
  • Graceful degradation if patch fails

2. Standardized API Response Format

Decision: All API responses follow a consistent structure with success, data, meta, and errors fields.

Rationale:

  • Predictable response handling in frontend
  • Easy to implement generic error handling
  • Supports pagination metadata uniformly
  • Clear separation between success and error states

3. JWT with Cookie Storage

Decision: Store JWT tokens in HTTP-only cookies instead of localStorage.

Rationale:

  • Protection against XSS attacks
  • Automatic inclusion in requests
  • Secure token refresh mechanism
  • Standard web security practice

4. Zustand for State Management

Decision: Use Zustand instead of Redux or Context API.

Rationale:

  • Minimal boilerplate compared to Redux
  • Better performance than Context for frequent updates
  • Simple API with hooks
  • Easy to test and mock

5. SQLite for Testing

Decision: Use SQLite in-memory database for backend tests instead of PostgreSQL.

Rationale:

  • Faster test execution (no Docker dependency)
  • Isolated test runs
  • No external database required for CI/CD
  • Sufficient for unit and integration tests

6. TipTap Rich Text Editor

Decision: Use TipTap (ProseMirror-based) instead of alternatives like Quill or Draft.js.

Rationale:

  • Modern, extensible architecture
  • TypeScript support
  • Active community and maintenance
  • Easy customization of toolbar and features

7. Category-based Organization

Decision: Implement optional category assignment with color coding.

Rationale:

  • Visual organization without forced hierarchy
  • Quick filtering by category
  • "Unassigned" category for uncategorized notes
  • User-defined colors for personalization

AI Tools Used

Cursor IDE with Claude

The primary AI tool used throughout development was Cursor IDE powered by Claude (Anthropic).

How AI Was Used

1. Code Generation & Implementation

  • Generated boilerplate code for Django models, serializers, and views
  • Created React components with TypeScript typing
  • Implemented complex features like the diff-match-patch integration
  • Generated comprehensive test suites for both backend and frontend

2. Architecture & Design Decisions

  • Discussed trade-offs for state management solutions
  • Designed the standardized API response format
  • Planned the testing strategy and coverage approach
  • Structured the project folder hierarchy

3. Debugging & Problem Solving

  • Diagnosed timezone issues in date formatting functions
  • Fixed test failures related to serializer context handling
  • Resolved Docker/Poetry dependency conflicts
  • Identified and fixed IntegrityError handling in category creation

4. Code Review & Refactoring

  • Consolidated duplicate date parsing logic into helper functions
  • Improved error handling in API endpoints
  • Refactored validation logic to handle missing request context
  • Optimized database queries with proper annotations

5. Documentation

  • Generated inline code comments and docstrings
  • Created API documentation with OpenAPI examples
  • Wrote test descriptions and assertions
  • Updated configuration files (gitignore, jest.config, etc.)

AI-Assisted Workflow Benefits

  1. Faster Iteration: Quick generation of boilerplate and repetitive code
  2. Consistency: Maintained coding standards across the codebase
  3. Learning: Exposure to best practices and alternative approaches
  4. Debugging: Rapid identification of issues and solutions
  5. Documentation: Comprehensive docs generated alongside code

Human Oversight

All AI-generated code was:

  • Reviewed for correctness and security
  • Tested against actual requirements
  • Modified when necessary to fit specific needs
  • Integrated with human-written architectural decisions

Testing

Running Tests

# Run all tests
make test

# Run with coverage
make test-cov

# Backend only
make test-backend
make test-backend-cov

# Frontend only
make test-frontend
make test-frontend-cov

Coverage Reports

  • Backend: HTML report in backend/htmlcov/
  • Frontend: HTML report in frontend/coverage/

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors