A Cornell Notes platform that combines the Cornell Note-taking method with AI-powered content generation, spaced repetition, analytics dashboards, and a social feed. Built for the DevDash 2026 hackathon (theme: "dashboards that turn data into action").
- Cornell Notes editor — structured sections for cues, notes, summary, example, and misconceptions; difficulty tagging; public/private toggle
- AI content generation — generate cue questions, summary, example, misconceptions, and topic tags from note content using Llama 4 Maverick
- Flashcards — AI-generate Q&A cards from notes; due/all review modes; tag-based deck browser
- Spaced repetition — SM2 algorithm schedules note reviews and flashcard reviews; quality ratings (0–5) update ease factor and interval
- Analytics dashboard — stats overview, weekly activity chart, mastery distribution chart, GitHub-style activity heatmap, due-notes list
- Full-text search — search across your own notes or include public notes
- Social feed — public notes feed with trending (time-decay score), recent, and following tabs; cursor-based infinite scroll
- Likes & bookmarks — toggle engagement from note detail/feed cards; counts denormalized on notes for fast reads
- Follow system — follow/unfollow users; follower and following lists on profiles
- User profiles — display name, bio, avatar; public note listing; follow counts
- File attachments — drag-and-drop uploads per note (single file per request); delete attachments; S3-backed in production
- PDF export — export any note as a formatted PDF via Flying Saucer
- Study guide generation — AI-generated study guide from selected notes or an entire tag
- Dark academic design system — custom CSS with Playfair Display, Source Serif 4, IBM Plex Mono, amber accent, activity heatmap, shimmer animations
| Layer | Technology |
|---|---|
| Framework | Spring Boot 4.0.2, Java 21 |
| UI | Thymeleaf + HTMX 2.0 + Bootstrap 5.3 + Chart.js 4.4 |
| Auth | Spring Security form login (session-based) |
| Database | H2 (dev), PostgreSQL on RDS (production) |
| AI | Spring AI 2.0.0-M2 + Llama 4 Maverick (OpenAI-compatible API) |
| Storage | AWS S3 (production), local filesystem (dev) |
| Flying Saucer 9.3 | |
| Build | Maven with wrapper |
| Deployment | EC2 t3.micro + RDS db.t3.micro (AWS Free Tier) |
- Java 21 (Amazon Corretto, Temurin, or any OpenJDK 21 distribution)
- Maven (included via wrapper — no separate install needed)
- Git
# Clone the repo
git clone <repo-url>
cd cortexnotes
# Build
./mvnw clean package
# Run (starts on port 8080, dev profile with H2 in-memory DB)
./mvnw spring-boot:runOpen http://localhost:8080 — you'll land on the public landing page. Log in or register, then:
| Field | Value |
|---|---|
| Username | dev |
| Password | password |
After login you'll be redirected to /dashboard with pre-seeded sample users, notes, tags, and review history.
src/main/java/com/example/cortexnotes/
├── CortexNotesApplication.java
├── config/
│ ├── SecurityConfig.java # Spring Security form login + session auth
│ ├── WebMvcConfig.java
│ ├── SearchConfig.java
│ └── DataSeeder.java # Seed data bootstrap (users, notes, tags, sessions)
├── controller/
│ ├── HomeController.java # Landing page (GET /) — redirects to /dashboard if authenticated
│ ├── AuthController.java # Login/register
│ ├── DashboardController.java # Analytics dashboard
│ ├── NoteController.java # Notes CRUD, attachments, PDF export, bookmarks
│ ├── FlashcardController.java # Flashcard deck, AI generation, review
│ ├── ReviewController.java # SM2 review tracking
│ ├── FeedController.java # Public feed, bookmark/follow toggles
│ ├── SearchController.java # Full-text search
│ ├── ProfileController.java # User profiles, follow lists
│ ├── AIController.java # Cornell AI generation with rate limiting
│ ├── StudyGuideController.java # Study guide generation
│ └── GlobalErrorController.java # @ControllerAdvice for 404/500 error pages
├── dto/
│ ├── NoteForm.java, NoteCardDto.java, NoteDetailDto.java
│ ├── FlashcardDto.java
│ ├── StatsDto.java, HeatmapCellDto.java, DueNoteDto.java
│ ├── TagDto.java, AuthorDto.java, FollowUserDto.java
│ ├── CornellAIResult.java, StudyGuideResult.java
├── entity/
│ ├── User.java # users table
│ ├── Note.java # notes table (denormalized like/bookmark counts)
│ ├── Tag.java, NoteTag.java # tags + many-to-many join
│ ├── Like.java, Bookmark.java # engagement (unique user-note constraint)
│ ├── Follow.java # follower/following (unique constraint)
│ ├── Flashcard.java # SM2 fields: easeFactor, intervalDays, nextReviewAt
│ ├── FlashcardReview.java # flashcard review events (quality, reviewedAt)
│ ├── StudySession.java # note review records + SM2 state snapshot
│ └── Attachment.java # file metadata (storageKey, url, contentType)
├── repository/
│ ├── UserRepository.java
│ ├── NoteRepository.java # Cursor-paginated feed + trending queries
│ ├── FlashcardRepository.java, FlashcardReviewRepository.java, StudySessionRepository.java
│ ├── TagRepository.java, NoteTagRepository.java
│ ├── LikeRepository.java, BookmarkRepository.java
│ ├── FollowRepository.java
│ └── AttachmentRepository.java
├── service/
│ ├── CustomUserDetailsService.java # Spring Security UserDetailsService impl
│ ├── NoteService.java # CRUD, like/bookmark toggle, tag reconciliation
│ ├── FlashcardService.java # Flashcard CRUD, SM2 scheduling
│ ├── ReviewService.java # SM2 review logic
│ ├── FeedService.java # Feed assembly, trending score, cursor pagination
│ ├── DashboardService.java # Stats, heatmap, weekly activity
│ ├── SearchService.java, FullTextSearchService.java, LikeSearchService.java
│ ├── CornellAIService.java # AI cue/summary/example/misconception generation
│ ├── StudyGuideService.java # AI study guide generation
│ ├── StorageService.java # Storage interface
│ ├── LocalStorageService.java # Dev: local filesystem
│ ├── S3StorageService.java # Prod: AWS S3
│ ├── PdfExportService.java # Flying Saucer PDF rendering
│ └── RateLimiterService.java # Per-user AI request rate limiting
└── util/
└── SM2Algorithm.java # SuperMemo 2 algorithm
src/main/resources/
├── application.properties # Dev profile config (H2, Llama AI, local storage)
├── static/
│ ├── css/styles.css # Full design system
│ └── js/app.js # HTMX CSRF, animations, tag input, charts
└── templates/
├── layout/base.html # Master layout (navbar, footer, CDN scripts)
├── auth/login.html, register.html
├── home/landing.html # Public landing page (standalone, no layout decorator)
├── notes/
│ ├── my-notes.html # Personal collection (tag filter, sort, infinite scroll)
│ ├── bookmarks.html # Saved bookmarks (cursor-paginated)
│ ├── editor.html # Cornell Notes create/edit form
│ └── detail.html # Cornell view + like/bookmark/edit/delete
├── flashcards/
│ ├── deck.html # Card browser (tag filter, delete)
│ └── review.html # Flashcard review (due/all modes, progress tracking)
├── feed/public-feed.html # Community feed (trending/recent/following tabs)
├── dashboard/index.html # Analytics dashboard (stats, charts, heatmap)
├── search/results.html # Full-text search results
├── profile/
│ ├── user.html # Public profile (notes, follow counts)
│ └── edit.html # Edit display name, bio, avatar
├── study-guide/result.html # AI-generated study guide
├── pdf/note-export.html # PDF export template
└── fragments/
├── note-card.html, feed-card.html, feed-cards-batch.html, feed-cards-error.html
├── flashcard-card.html
├── like-button.html, bookmark-button.html, follow-button.html
├── review-result.html, stats-panel.html, notes-page.html, bookmarks-page.html
├── ai-results.html, study-guide-result.html
└── follow-list-modal.html
| Method | URL | Description |
|---|---|---|
| GET | / |
Landing page (redirects to /dashboard if authenticated) |
| GET | /dashboard |
Analytics dashboard (stats, heatmap, charts) |
| GET | /actuator/health |
Public health check endpoint |
| Method | URL | Description |
|---|---|---|
| GET | /notes/my |
My Notes (tag filter, sort, infinite scroll) |
| GET | /notes/bookmarks |
Bookmarked notes (cursor-paginated) |
| GET | /notes/new |
New note editor |
| GET | /notes/edit/{id} |
Edit note (owner only) |
| GET | /notes/{id} |
Note detail view |
| POST | /notes/save |
Create or update note |
| POST | /notes/delete/{id} |
Delete note (owner only) |
| GET | /notes/{id}/export-pdf |
Export note as PDF |
| POST | /notes/{id}/attachments |
Upload attachment(s) |
| POST | /notes/{noteId}/attachments/{attachmentId}/delete |
Delete attachment |
| Method | URL | Description |
|---|---|---|
| GET | /flashcards |
Flashcard deck browser |
| GET | /flashcards/review |
Review session (mode=due or all, optional note/tag filter) |
| POST | /api/flashcards/generate/{noteId} |
AI-generate flashcards from note |
| POST | /api/flashcards/{id}/review |
Submit SM2 rating for a flashcard |
| DELETE | /api/flashcards/{id} |
Delete flashcard |
| POST | /api/review/{id} |
Submit SM2 rating for a note |
| Method | URL | Description |
|---|---|---|
| GET | /feed |
Public feed (trending / recent / following tabs, infinite scroll) |
| POST | /api/notes/{id}/like |
Toggle like (HTMX, returns fragment) |
| POST | /api/notes/{id}/bookmark |
Toggle bookmark (HTMX, returns fragment) |
| POST | /api/users/{id}/follow |
Toggle follow (HTMX, returns fragment) |
| Method | URL | Description |
|---|---|---|
| GET | /user/{username} |
Public profile page |
| GET | /user/{username}/edit |
Edit profile form |
| POST | /user/{username}/edit |
Save profile changes |
| GET | /user/{username}/follow-counts |
Follower/following counts (HTMX) |
| GET | /user/{username}/follow-list |
Follower/following list modal (HTMX) |
| Method | URL | Description |
|---|---|---|
| POST | /api/ai/generate |
Generate cues, summary, example, misconceptions + tags from note content |
| POST | /study-guide/generate |
Generate study guide from selected notes or tag |
| Method | URL | Description |
|---|---|---|
| GET | /search |
Full-text search (own notes, optionally public notes) |
| GET | /auth/login |
Login page |
| GET | /auth/register |
Registration page |
| POST | /auth/register |
Register new user |
| POST | /auth/logout |
Logout |
H2 in-memory with ddl-auto=create-drop. Schema is generated from JPA entities on startup. DataSeeder seeds sample users, notes, tags, follows, likes/bookmarks, and study sessions (runs when the users table is empty).
H2 console at http://localhost:8080/h2-console:
| Field | Value |
|---|---|
| JDBC URL | jdbc:h2:mem:cortexnotes |
| Username | sa |
| Password | (empty) |
| Table | Description |
|---|---|
users |
Accounts — username, email, displayName, bio, avatarUrl, passwordHash, streakCount |
notes |
Cornell Notes — cueColumn, notesSection, summary, example, misconceptions, sourceText, difficulty, isPublic, like_count, bookmark_count (denormalized) |
tags |
Unique tag names |
note_tags |
Note ↔ Tag many-to-many join |
likes |
User-note likes (unique constraint, denormalized count on notes) |
bookmarks |
User-note bookmarks (unique constraint, denormalized count on notes) |
follows |
Follower ↔ following pairs (unique constraint) |
flashcards |
Q&A cards with SM2 fields: easeFactor, intervalDays, repetitions, nextReviewAt |
flashcard_reviews |
Flashcard review events: quality (0-5), reviewedAt |
study_sessions |
Per-review records: quality rating (0-5), SM2 state snapshot, reviewedAt, nextReviewAt |
attachments |
File metadata: fileName, storageKey, contentType, fileSize, url |
Dark academic observatory theme with custom CSS variables:
- Colors: Deep navy backgrounds (#0B0E11, #141920), amber accent (#E8A838), warm text (#E8E0D4)
- Typography: Playfair Display (headings), Source Serif 4 (body), IBM Plex Mono (UI/code)
- Components: Note cards with difficulty-colored edges, glassmorphic navbar, ruled-paper editor, GitHub-style activity heatmap, float-label forms
- Animations: Fade-slide-up reveals, shimmer loading, fire flicker (streak), count-up numbers
# Build
./mvnw clean package
# Run
./mvnw spring-boot:run
# Run all tests
./mvnw test
# Run single test
./mvnw test -Dtest=CortexNotesApplicationTestsThe AI backend uses Meta's Llama-4-Maverick-17B-128E-Instruct-FP8 model via an OpenAI-compatible API (api.llama.com). Set LLAMA_API_KEY in your environment before running:
export LLAMA_API_KEY=your_key_here
./mvnw spring-boot:runWithout the key the app starts normally but AI features return an error.