A Google Keep–inspired notes application built with Django and React, focused on design fidelity, thoughtful UX, and clean full-stack architecture.
- Match the provided Figma design as closely as possible
- Deliver all required functionality within a 72-hour constraint
- Demonstrate senior-level tradeoff analysis, code quality, and UX thinking
- Use AI tools responsibly to accelerate (not replace) engineering judgment
The UI closely matches the provided Figma specifications:
- Category-based sidebar with color-coded indicators
- Card-based notes grouped by date (Today / Yesterday / Earlier)
- Full-screen note editor
- Minimal, distraction-free layout
- Typography and spacing aligned with design tokens
- Framework: Django (REST API with DRF)
- Database: SQLite (development), PostgreSQL-ready
- Auth: JWT (SimpleJWT)
- Data Model: Category, Note, NoteVersion
- API Style: RESTful, user-scoped, category-filterable
- Framework: React 18 (Vite)
- Styling: Tailwind CSS with custom tokens
- Routing: React Router v6
- State: React hooks + context (no global state library)
- Networking: Axios with token refresh handling
React was chosen to maximize delivery speed and clarity within the time limit. Migration to Next.js would be largely structural and straightforward.
docker compose up --build- Backend:
http://localhost:8000 - Frontend:
http://localhost:5173
The database is persisted in a Docker volume. Run docker compose down -v to remove volumes and reset data.
cd backend/notes_project
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r ../requirements.txt
python manage.py migrate
python manage.py seed_categories
python manage.py runserverBackend: http://localhost:8000
cd frontend
npm install
npm run devFrontend: http://localhost:5173
- User authentication (signup / login)
- Create, edit, delete notes
- Fixed categories with filtering
- Autosave with debounce (500ms)
- Date-based note grouping
- Empty states and responsive layout
- Version History (last 5 versions per note, read-only)
- Restore Version (one-click rollback)
- Keyboard Shortcut (
Nto create note)
- Why: Prevents data loss and improves UX
- How: Debounced PATCH requests (500ms)
- Tradeoff: Slight save delay, reduced network noise
- Why: Safety net for editing mistakes
- How: Snapshot stored on each save, capped at 5
- Tradeoff: Storage overhead vs. simplicity
- Why: Matches Figma exactly and simplifies UX
- Tradeoff: Less flexibility, but clearer scope
- Why: App complexity doesn’t justify Redux
- Benefit: Easier reasoning and review
AI tools (Claude and Cursor) were used as productivity accelerators—similar to advanced IDE features or pair programming.
They were used to:
- Scaffold boilerplate and repetitive patterns
- Brainstorm UX enhancements and optional features
- Validate architectural approaches and edge cases
- Suggest refactors and naming improvements
All AI-generated output was:
- Reviewed line-by-line
- Adapted to project-specific constraints
- Tested locally before commit
- Rejected when it didn’t meet quality or clarity standards
All final decisions, tradeoffs, and implementations were made manually.
backend/
notes_project/
notes_api/
models.py
serializers.py
views.py
urls.py
frontend/
src/
components/
pages/
services/
utils/
context/
Structure evolved slightly as features were added, while maintaining clear separation of concerns.
- JWT-based auth
- ORM-level SQL injection protection
- Password validation enforced
- CORS configured for development
- Full-text search
- Rich-text / Markdown editor
- Offline support
- Pagination and virtualization
- Automated testing (unit + E2E)
Built with attention to UX, maintainability, and delivery under constraints.