Do LeetCode Top 100
Finished LeetCode Top 100
I want to Learn English
Finished Learn English
Practice LeetCode binary search problems, 45 min
Finished LeetCode binary search problems
reading DDIA chapter 4
Finished reading DDIA chapter 4
Personal growth management platform with goal tracking, habit check-ins, people network, and AI-powered notes. Hand-drawn anime sketch aesthetic inspired by Xiaohongshu/Instagram/Weibo.
# Terminal 1 — Backend
cd backend && .venv/bin/python app.py
# Terminal 2 — Frontend
cd frontend && npm run dev
Open http://localhost:3000 and click "Try demo account" to log in.
Ports 5001, 5002, 8322 are reserved and not used by this project.
Set Goals → Break into Tasks → Daily Habits → Write Notes → Review Stats → Adjust Direction
┌──────┬──────┬──────┬──────┬──────┐
│ Today│ Goals│ Notes│People│ Me │
└──────┴──────┴──────┴──────┴──────┘
Streak counter — consecutive learning days with fire icon
4 stat cards : Total Nodes, Completed, Streak Days, Completion Rate
Active Goals — progress bars with deadlines and days remaining, click to jump to Goals
Daily Habit Check-in — tap to complete habits with estimated duration display
This Week's Schedule — compact list with time ranges, status badges, linked people/nodes
Active Learning — tree nodes in progress with hours progress bars
Recent Notes — latest notes with AI summaries and relative timestamps
North Stars — quick-access to role models, click to jump to People
Weekly Summary — completions, hours, dimensions touched, best note score
Responsive 2-column grid on desktop, stacked on mobile
Goal cards — title, description, deadline, level badge (week/month/quarter), progress bar
Progress computed from linked skill tree node completions
Expandable detail showing linked tree nodes with status + accumulated hours
Create / Complete / Delete goals with inline form
Filter tabs : All / Active / Completed
People Tab (Star Map + List)
D3.js force-directed graph with cosmic dark background and glow effects
Person nodes show initials inside larger circles (avatar-like), with legible serif font labels
Relationship lines clearly visible — warm green strokes with type labels (mentor, collaborator, etc.)
Link labels shown at edge midpoints; hover highlights individual connections
North Star designation with golden halo and pulsing glow
Growth route dashed lines connecting you to your North Star(s) — properly animated in tick
Role/relation subtitle shown below each name
Drag-and-drop node repositioning, zoom/pan navigation
Click a star to preview a profile card with tabbed interface (Skills | Schedule | Notes), then edit
Subgraph search — typing a name fades all non-matching nodes, showing only the matched person and their 1-degree connections as a focused subgraph; clearing search restores the full constellation
Gap Analysis radar chart overlay (You vs North Star skill comparison)
Skill scores auto-derived — no manual skill rating; self scores computed from skill tree completion per dimension
Web search auto-fill — search a person's name to auto-populate role and bio
No node clipping — overflow-hidden removed, increased container height
Dual view modes — toggle between indented list and D3.js tree layout (default: tree)
D3 tree visualization — d3.tree() layout with curved branch connections, status-colored circles, task type indicators, zoom/pan navigation
Expandable list view per dimension (tech, soft skills, industry)
Visual tree connection lines — vertical/horizontal connectors between parent and child nodes (list mode)
Lit-up path coloring — completed/active nodes show green connection lines, locked nodes show dim lines
Status-colored nodes: locked (grey), active (green pulse), completed (green), pruned (red strikethrough)
Hand-drawn doodle icons for task types (reading, practice, video, social)
Completed node titles highlighted in green
Add/delete nodes with parent selection
Node detail panel with status change, linked mentor, accumulated hours progress bar , linked schedule blocks, linked notes — all items clickable for cross-navigation to schedule/notes views
Accumulated hours tracking — completing a schedule block automatically adds hours to the linked tree node
Auto-generated learning notes — completing a schedule block creates a linked note as a learning record
Progress bar per dimension
Share skill trees via shareable links
FullCalendar weekly view with drag-and-drop and resize
Compact height (450px) — fits in viewport without scrolling
Narrowed time range (07:00-23:00) — no wasted empty rows
Sketch-styled event action sheet (Complete / Skip / Delete)
Auto-generate schedule from learning priorities
Manual block creation via time slot selection or button
Node & Person selectors — link schedule blocks to skill tree nodes and people when creating
Toast notifications for all actions
Enhanced card grid (2 columns) with quality score badges (color-coded: green >=70, amber 30-69, red <30)
AI summary preview on each card — one-line AI-generated summary below title
Quality scoring — rule-based 0-100 score (word count, headings, code blocks, links, reflection keywords, bullet points). High-quality notes (>=70) boost linked skill tree node progress.
One-click scoring — "Score" button on card hover computes quality immediately
AI Summary generation — "AI Summary" button generates LLM-powered one-sentence summary
Category filter tabs and full-text search
Pin/unpin notes (pinned notes float to top)
Link notes to people, dimensions, or tree nodes
Markdown editor — split-pane with live preview (textarea left, rendered right)
LLM chat panel — collapsible AI chat sidebar with SSE streaming responses
Share notes via shareable links
Learning Resources (RSS)
400+ RSS feeds from BestBlogs OPML (tech, AI, design, business blogs from Hugging Face, OpenAI, Meta, LangChain, ByteByteGo, etc.)
Feed browser — browse all available feeds, fetch articles from any feed with one click
Resource cards — title, source, summary, date, with bookmark/read toggles and external link
Category filters — All | Tech | AI | Design | Business | Bookmarked
Read/bookmarked state persisted to database
Articles stored locally in learning_resources table
LLM Chat — streaming conversation with context from the current note
AI Note Summary — one-click summary generation (LLM-powered, falls back to content snippet)
Note Quality Scoring — rule-based 0-100 scoring with LLM summary generation
Web Search — DuckDuckGo-powered person lookup with LLM extraction
ReAct Agent — iterative search + reasoning for complex queries
Generate shareable links for notes, people, and skill trees
One-click copy to clipboard
Public share resolution via token
Hand-drawn anime sketch aesthetic throughout the entire app
33 custom SVG doodle icons (SketchIcons.tsx)
Notebook paper grid background with wobbly borders
Asymmetric border-radius (12px 4px 12px 4px) for a hand-drawn feel
Offset box-shadows simulating pen strokes
Georgia + Times New Roman + Source Han Serif SC (Noto Serif SC) font system
Custom toast notification system (success/error/info/warning)
Custom confirm dialog
Profile cards with tabbed data views (Skills progress bars, Schedule, Notes) — items clickable for cross-navigation
Bottom sheet modals on mobile, centered on desktop
Responsive: desktop top nav + mobile bottom nav
Layer
Technology
Version
Frontend Framework
React + TypeScript
18.3.1 + 5.6.3
Build Tool
Vite
5.4.11
CSS
Tailwind CSS
3.4.15
State Management
Zustand
5.0.0
Charts / Graphs
D3.js
7.9.0
Radar Charts
Recharts
2.13.0
Calendar
FullCalendar
6.1.15
Markdown
react-markdown + remark-gfm
10.1.0 + 4.0.1
HTTP Client
Axios
1.7.0
Routing
react-router-dom
6.28.0
Icons
Custom hand-drawn SVGs (SketchIcons.tsx)
--
Backend
Python Flask
3.1.0
CORS
flask-cors
5.0.1
RSS Parsing
feedparser
6.0.12
Database
SQLite (via stdlib sqlite3)
--
Auth
werkzeug password hashing
--
Fonts
Georgia, Times New Roman, Noto Serif SC
Google Fonts
Package Managers
npm (frontend), uv (Python backend)
--
GrowthOS/
.env # LLM + search config (user fills in)
BestBlogs_RSS_ALL.opml # 400+ RSS feed sources
BestBlogs_RSS_ALL-1.opml # Backup OPML
improve.md # Ordered improvement changelog (Chinese)
need.md # Full product spec / feature list (Chinese)
README.md # This file
backend/
app.py # Flask API — 55+ REST endpoints (1461 lines)
db.py # SQLite helpers + seed data loader (251 lines)
schema.sql # 15 tables (193 lines)
seed_data.json # Demo data: 1 user, 12 dimensions, 8 people, 20 tree nodes (478 lines)
requirements.txt # flask, flask-cors, feedparser
.venv/ # Python virtual environment
growthOS.db # SQLite database (auto-created on first run)
frontend/
index.html # HTML entry point
package.json # Dependencies & scripts
vite.config.ts # Vite config: port 3000, proxy /api -> :5005
tailwind.config.js # Sketch color palette, fonts, animations
tsconfig.json # TypeScript strict mode, ES2020
postcss.config.js # Tailwind + Autoprefixer
src/
main.tsx # React entry point (10 lines)
App.tsx # Auth routing + global overlays (51 lines)
store.ts # Zustand global state (119 lines)
api.ts # Axios API layer — all endpoint calls (155 lines)
types.ts # TypeScript interfaces (178 lines)
index.css # Notebook paper BG, sketch cards, markdown styles (219 lines)
components/
Layout.tsx # Shell: top nav + bottom mobile nav + view router (102 lines)
Dashboard.tsx # Homepage: stats, gaps, schedule, notes, weekly report (314 lines)
StarMap.tsx # D3.js constellation force graph (375 lines)
SkillTree.tsx # D3 tree + list view with toggle + share (506 lines)
ScheduleView.tsx # FullCalendar integration (237 lines)
NotesView.tsx # Markdown editor + LLM chat + quality scoring (549 lines)
ResourcesView.tsx # RSS feed browser + resource cards (235 lines)
NodeDetailPanel.tsx # Node detail: hours, schedule, notes links (194 lines)
PersonCard.tsx # Profile card + tabs + share (235 lines)
PersonModal.tsx # Add/edit person + web search (158 lines)
GapAnalysis.tsx # Recharts radar chart comparison (71 lines)
EventActionSheet.tsx # Sketch-styled event actions (80 lines)
SketchIcons.tsx # 33 hand-drawn SVG icon components (322 lines)
StatsBar.tsx # Stats display cards (28 lines)
Login.tsx # Watercolor gradient login (106 lines)
Toast.tsx # Sketch toast notifications (59 lines)
ConfirmDialog.tsx # Sketch confirm dialog (62 lines)
Total source code : ~6,900 lines (backend ~1,900 + frontend ~5,000)
Database Schema (15 tables)
Column
Type
Notes
id
INTEGER PK
Auto-increment
username
TEXT UNIQUE
Login identifier
password_hash
TEXT
werkzeug hash
display_name
TEXT
Shown in UI
avatar_url
TEXT
Optional
weekly_hours
REAL
Default 10
created_at
TEXT
ISO timestamp
Skill dimensions (e.g. "System Design", "Python", "Communication")
Column
Type
Notes
id
INTEGER PK
user_id
FK users
name
TEXT
Dimension name
category
TEXT
tech / soft / industry
color
TEXT
Hex color code
Stars in the constellation
Column
Type
Notes
id
INTEGER PK
user_id
FK users
name
TEXT
Person name
role
TEXT
Job title / role
relation_type
TEXT
friend / colleague / mentor / classmate / idol
is_self
INTEGER
0 or 1
is_north_star
INTEGER
0 or 1
avatar_color
TEXT
Hex color
bio
TEXT
Short biography
pos_x, pos_y
REAL
Saved graph position (nullable)
created_at
TEXT
ISO timestamp
Skill scores for each person on each dimension (0-5)
Column
Type
Notes
id
INTEGER PK
person_id
FK people
dimension_id
FK dimensions
score
INTEGER
0-5, CHECK constraint
UNIQUE(person_id, dimension_id)
Connections between people
Column
Type
Notes
id
INTEGER PK
user_id
FK users
person_a_id
FK people
person_b_id
FK people
rel_type
TEXT
knows / close / mentor / collaborator
strength
INTEGER
1 (weak) / 2 (normal) / 3 (strong)
Skill tree nodes (adjacency list via parent_id)
Column
Type
Notes
id
INTEGER PK
user_id
FK users
dimension_id
FK dimensions
parent_id
FK tree_nodes
Nullable (root nodes)
title
TEXT
Node title
description
TEXT
est_hours
REAL
Estimated hours
accumulated_hours
REAL
Hours logged from schedule completions
task_type
TEXT
reading / practice / video / social
status
TEXT
locked / active / completed / pruned
resource_url
TEXT
Optional link
linked_person_id
FK people
Nullable mentor link
order_idx
INTEGER
Sort order
Calendar time blocks
Column
Type
Notes
id
INTEGER PK
user_id
FK users
node_id
FK tree_nodes
Nullable
linked_person_id
FK people
Nullable
title
TEXT
Block title
start_time
TEXT
ISO datetime
end_time
TEXT
ISO datetime
status
TEXT
planned / completed / skipped
color
TEXT
Hex color
Tracks completion events
Column
Type
Notes
id
INTEGER PK
user_id
FK users
node_id
FK tree_nodes
completed_at
TEXT
ISO timestamp
actual_hours
REAL
Weekly recurring available times
Column
Type
Notes
id
INTEGER PK
user_id
FK users
day_of_week
INTEGER
0=Mon, 6=Sun
start_time
TEXT
"HH:MM"
end_time
TEXT
"HH:MM"
energy_level
TEXT
high / low / fragment
Column
Type
Notes
id
INTEGER PK
user_id
FK users
title
TEXT
content
TEXT
Markdown content
category
TEXT
general / meeting / learning / idea / project
linked_person_id
FK people
Nullable
linked_dimension_id
FK dimensions
Nullable
linked_node_id
FK tree_nodes
Nullable
is_pinned
INTEGER
0 or 1
summary
TEXT
LLM-generated summary
quality_score
INTEGER
0-100 rule-based score
ai_summary
TEXT
One-sentence AI summary
created_at
TEXT
ISO timestamp
updated_at
TEXT
ISO timestamp
Column
Type
Notes
id
INTEGER PK
user_id
FK users
note_id
FK notes
Nullable
role
TEXT
user / assistant
content
TEXT
created_at
TEXT
ISO timestamp
RSS feed articles
Column
Type
Notes
id
INTEGER PK
user_id
FK users
title
TEXT
Article title
url
TEXT
Article URL
summary
TEXT
Extracted summary
source
TEXT
Feed name
category
TEXT
tech / ai / design / business
quality_score
INTEGER
fetched_at
TEXT
ISO timestamp
is_read
INTEGER
0 or 1
is_bookmarked
INTEGER
0 or 1
Links between resources and skill tree nodes
Column
Type
Notes
id
INTEGER PK
resource_id
FK learning_resources
node_id
FK tree_nodes
relevance_score
REAL
Default 0.5
linked_at
TEXT
ISO timestamp
UNIQUE(resource_id, node_id)
Shareable link tokens
Column
Type
Notes
id
INTEGER PK
user_id
FK users
token
TEXT UNIQUE
URL-safe random token
resource_type
TEXT
note / person / tree
resource_id
INTEGER
created_at
TEXT
ISO timestamp
expires_at
TEXT
Nullable expiry
Method
Path
Description
POST
/api/auth/register
Register new user (username, password, display_name)
POST
/api/auth/login
Login -> returns user object
GET
/api/auth/me
Current user (via X-User-Id header)
Method
Path
Description
GET
/api/bootstrap
Load all data at once (user, dimensions, people, relationships, gap, trees, schedule, notes, chat history, stats)
Method
Path
Description
GET
/api/dimensions
List all dimensions
POST
/api/dimensions
Create dimension (name, category, color)
PUT
/api/dimensions/:id
Update dimension
DELETE
/api/dimensions/:id
Delete dimension
Method
Path
Description
GET
/api/people
List people with skills
POST
/api/people
Create person (name, role, relation_type, is_self, bio, avatar_color, is_north_star)
PUT
/api/people/:id
Update person fields
DELETE
/api/people/:id
Delete person + cascade
PUT
/api/people/:id/skills
Bulk set skill scores (skills: [{dimension_id, score}])
PUT
/api/people/:id/north-star
Toggle North Star status
GET
/api/people/:id/schedule
Person's linked schedule blocks (last 10)
GET
/api/people/:id/notes
Person's linked notes (last 10)
Method
Path
Description
GET
/api/relationships
List all relationships
POST
/api/relationships
Create relationship (person_a_id, person_b_id, rel_type, strength)
PUT
/api/relationships/:id
Update relationship
DELETE
/api/relationships/:id
Delete relationship
Method
Path
Description
GET
/api/gap-analysis
Compute skill gaps: self score from tree completion per dimension vs target (5.0). Returns dimensions[] with self_score, target_score, gap
Method
Path
Description
GET
/api/trees?dimension_id=N
List tree nodes for dimension
POST
/api/trees
Create node (dimension_id, title, parent_id, est_hours, task_type, status, linked_person_id)
PUT
/api/trees/:id
Update node fields
DELETE
/api/trees/:id
Delete node + all descendants (recursive CTE)
PUT
/api/trees/:id/status
Set status (locked/active/completed/pruned)
PUT
/api/trees/:id/complete
Mark completed + create progress log
GET
/api/trees/:id/schedule
Node's linked schedule blocks (last 10)
GET
/api/trees/:id/notes
Node's linked notes (last 10)
Method
Path
Description
GET
/api/schedule?start=&end=
List blocks in date range
POST
/api/schedule
Create block (title, start_time, end_time, node_id, linked_person_id, color)
PUT
/api/schedule/:id
Update block. Side effects on status->completed : adds hours to linked tree node, creates auto-generated learning note
DELETE
/api/schedule/:id
Delete block
POST
/api/schedule/auto-generate
Auto-fill schedule: clears planned blocks, assigns active/locked nodes to time slots for current week
Method
Path
Description
GET
/api/time-slots
List weekly time slot templates
POST
/api/time-slots
Create slot (day_of_week, start_time, end_time, energy_level)
DELETE
/api/time-slots/:id
Delete slot
Method
Path
Description
GET
/api/progress/stats
total_nodes, completed_nodes, streak_days, completion_rate, hours_logged
GET
/api/progress/weekly-report
This week: completions, hours, dimensions touched, completed node names
Method
Path
Description
GET
/api/notes?category=&search=
List notes (filtered, sorted by pinned + updated_at)
POST
/api/notes
Create note (title, content, category, linked_person_id, linked_dimension_id, linked_node_id, is_pinned)
PUT
/api/notes/:id
Update note fields
DELETE
/api/notes/:id
Delete note
PUT
/api/notes/:id/pin
Toggle pin
POST
/api/notes/:id/summarize
LLM summary (2-3 sentences) -> saved to summary field
POST
/api/notes/:id/score
Rule-based quality scoring (0-100). If score >= 70 and note linked to node, adds +0.5 accumulated hours
POST
/api/notes/:id/ai-summary
LLM one-sentence summary -> saved to ai_summary field. Falls back to content snippet if no API key
Method
Path
Description
POST
/api/chat
Non-streaming chat. Saves all messages to chat_messages. Body: {note_id?, messages: [{role, content}]}
POST
/api/chat/stream
SSE streaming chat. Word-by-word data: {"delta":"..."} events, ends with {"done":true}
GET
/api/chat/history?note_id=N
Chat history for a note
Method
Path
Description
POST
/api/search/web
DuckDuckGo web search. Body: {query}. Returns [{title, url, snippet}]
POST
/api/search/person
Web search + LLM extraction. Body: {name}. Returns {name, role, bio, source_urls}
Method
Path
Description
GET
/api/dashboard
Aggregated: stats, north_stars, top_gaps (3), week_schedule, recent_notes (5), active_nodes (5), weekly_report
Learning Resources (RSS)
Method
Path
Description
GET
/api/resources/feeds
Parse BestBlogs OPML -> list of {title, url} feed entries
POST
/api/resources/fetch
Fetch RSS feed via feedparser. Body: {url, category?}. Inserts up to 20 new articles (deduped by URL)
GET
/api/resources?category=&bookmarked=
List resources (50 max, sorted by fetched_at)
PUT
/api/resources/:id
Update is_read / is_bookmarked
DELETE
/api/resources/:id
Delete resource
Method
Path
Description
POST
/api/share
Generate share token. Body: {resource_type: "note"/"person"/"tree", resource_id}. Returns {token, url}
GET
/api/share/:token
Resolve shared resource -> returns resource data
Frontend State (Zustand Store)
interface AppState {
user : User | null
dimensions : Dimension [ ]
people : Person [ ]
relationships : Relationship [ ]
gapItems : GapItem [ ]
treesByDimension : Record < number , TreeNode [ ] > // keyed by dimension ID
scheduleBlocks : ScheduleBlock [ ]
notes : Note [ ]
stats : Stats | null
currentView : ViewType // 'dashboard'|'starmap'|'skilltree'|'schedule'|'notes'|'resources'
selectedDimensionId : number | null
selectedPersonId : number | null
loading : boolean
// Actions
setView ( v : ViewType )
setSelectedDimension ( id : number | null )
setSelectedPerson ( id : number | null )
setUser ( u : User | null )
loadBootstrap ( ) // Fetches all data in one call
refreshPeople ( )
refreshRelationships ( )
refreshDimensions ( )
refreshGap ( )
refreshTrees ( dimensionId : number )
refreshSchedule ( start : string , end : string )
refreshStats ( )
refreshNotes ( params ?: { category ?: string ; search ?: string } )
}
Data flow : Login -> loadBootstrap() -> populates entire store -> views read from store + call specific refresh on mutations.
User { id , username , display_name , avatar_url , weekly_hours }
Dimension { id , user_id , name , category , color }
Person { id , user_id , name , role , relation_type , is_self , is_north_star , avatar_color , bio , pos_x , pos_y , skills [ ] }
PersonSkill { dimension_id , score }
Relationship { id , person_a_id , person_b_id , rel_type , strength }
TreeNode { id , user_id , dimension_id , parent_id , title , description , est_hours , accumulated_hours , task_type , status , resource_url , linked_person_id , order_idx , children ? }
ScheduleBlock { id, node_id, linked_person_id, title, start_time, end_time, status, color, node_title ?, person_name ? }
TimeSlot { id, day_of_week, start_time, end_time, energy_level }
GapItem { dimension_id , name , color , self_score , target_score , gap }
Stats { total_nodes, completed_nodes, streak_days, completion_rate, hours_logged }
Note { id, user_id, title, content, category, linked_person_id, linked_dimension_id, linked_node_id, is_pinned, summary, quality_score, ai_summary, created_at, updated_at }
ChatMessage { id, note_id, role, content, created_at }
LearningResource { id, title, url, summary, source, category, quality_score, fetched_at, is_read, is_bookmarked }
ShareToken { token, resource_type, resource_id, created_at }
WeeklyReport { week_start, completions, hours_logged, dimensions_touched [ ] , completed_nodes [ ] , best_note, focus_suggestion }
DashboardData { stats, north_stars [ ] , top_gaps [ ] , week_schedule [ ] , recent_notes [ ] , active_nodes [ ] , weekly_report }
ViewType = 'dashboard' | 'starmap' | 'skilltree' | 'schedule' | 'notes' | 'resources'
Custom Icons (33 SVGs in SketchIcons.tsx)
All icons are hand-drawn style SVGs with stroke: currentColor, strokeWidth: 2, strokeLinecap: round.
Icon
Used In
IconStars
Star Map nav, Login, Layout logo
IconTree
Skill Tree nav, Dashboard
IconCalendar
Schedule nav, Dashboard
IconNote
Notes nav, Dashboard
IconPlus
Add buttons (people, nodes, schedule, notes)
IconSearch
Search bars
IconSparkle
Login, AI features
IconTrash
Delete buttons
IconX
Close / dismiss
IconCheck
Completion indicators
IconStar
North Star indicators
IconPin
Note pinning
IconSend
Chat send button
IconShare
Share buttons
IconUser
User avatar, social task type
IconLogout
Logout button
IconWand
Auto-generate schedule
IconClock
Time displays
IconGlobe
External link indicator
IconChat
Chat panel toggle
IconEye
Preview / view
IconChevronDown
Expandable sections
IconChevronRight
Collapsed sections
IconRocket
Dashboard, Login
IconScissors
Pruning
IconBook
Reading task type, Resources nav
IconTarget
Completion rate, gap analysis
IconZap
Streak, practice task type
IconArrowRight
Navigation arrows
IconExternalLink
External links
IconLock
Locked nodes
IconPlay
Video task type
IconLoader
Loading spinners
Token
Hex
Usage
surface
#FFFBF5
Page background
paper
#FFF8EE
Card backgrounds
primary
#5B8C5A
Green -- buttons, active states, nav
primary-light
#8BBF8A
Completed nodes
primary-dark
#3D6B3C
Button borders, hover
accent
#C084FC
Purple -- accent buttons, notes
accent-dark
#9333EA
Accent borders
rose
#F472B6
Pink -- errors, pruned nodes
sky
#60A5FA
Blue -- reading tasks
gold
#F59E0B
Yellow -- streak, North Star glow
ink
#2D2B2A
Primary text
cosmos
#1A1625
Star map dark background
sketch-border
#C4B5A0
Card / section borders
sketch-line
#8B7E6E
Muted text, hover shadows
sketch-faint
#E8DFD1
Subtle borders
Cards: 12px 4px 12px 4px -- asymmetric hand-drawn feel
Buttons: 8px 3px 8px 3px
Badges: 6px 2px 6px 2px
Sketchy (Tailwind class): 255px 15px 225px 15px/15px 225px 15px 255px
sketch: 3px 3px 0px #C4B5A0 -- offset pen stroke
sketch-hover: 4px 4px 0px #8B7E6E -- hover lift
sketch-sm: 2px 2px 0px #C4B5A0 -- buttons
Headings : Georgia, "Noto Serif SC", serif
Body text : "Times New Roman", "Noto Serif SC", Georgia, serif
Chinese fallback : Noto Serif SC (Google Fonts)
Name
Duration
Usage
pulse-glow
2s infinite
North Star pulsing, active nodes
float
3s infinite
Login background stars
grow-in
0.5s forwards
Node appear
wobble
0.5s
Interaction feedback
scribble
0.3s forwards
Line draw effect
wiggle
2s infinite
Subtle idle animation
Class
Purpose
.sketch-card
Card container with paper bg, sketch border, offset shadow, hover lift
.glass-card
Same as sketch-card without hover effect
.btn-primary
Green primary button
.btn-accent
Purple accent button
.btn-ghost
Transparent button with hover border
.input-field
Text input with sketch border
.label-text
Uppercase label
.nav-item
Navigation button
.nav-item-active
Active nav state
.nav-item-inactive
Inactive nav state
.badge
Small tag/label
.stat-card
Statistics display
.sketch-underline
SVG wavy underline decoration
Edit .env in the project root:
LLM_API_KEY = sk-your-key-here
LLM_BASE_URL = https://api.openai.com/v1
LLM_MODEL = gpt-4o-mini
SEARCH_ENABLED = true
Any OpenAI-compatible API works (OpenAI, Anthropic via proxy, DeepSeek, local models, etc.).
Features powered by LLM :
Note AI summaries (one-sentence via /api/notes/:id/ai-summary)
Note quality scoring (rule-based, with LLM summary fallback)
Chat panel in note editor (SSE streaming via /api/chat/stream)
Web search person extraction (DuckDuckGo search + LLM parsing)
LLM call flow (_llm_request in app.py):
Builds {model, messages} payload
POSTs to {LLM_BASE_URL}/chat/completions
Extracts choices[0].message.content
Returns (content, error, status_code) tuple
Streaming (chat/stream endpoint): Gets full response from LLM, then simulates SSE by splitting into words and sending each as a data: {"delta": "word "} event.
Cross-Module Linkage (Core Innovation)
The system creates a feedback loop between all modules:
Star Map (People) <-> Skill Trees (Learning) <-> Schedule (Time) <-> Notes (Reflection)
| | | |
+------ linked via ----+------ linked via ------+------ linked via ----+
person_id node_id schedule -> note auto-creation
Schedule completion -> Hours accumulation : Completing a schedule block adds its duration to the linked tree node's accumulated_hours
Schedule completion -> Auto-note : Completing a block auto-creates a learning note linked to the same node and person
Note quality -> Skill boost : Notes scored >= 70 add +0.5 hours to linked tree node
Gap analysis auto-compute : Self scores derived from tree completion percentage per dimension (not manual input)
Cross-navigation : PersonCard shows linked schedule + notes. NodeDetailPanel shows linked schedule + notes + mentor. All clickable to navigate.
Frontend checks localStorage.user_id on mount
If exists -> calls GET /api/auth/me to validate
If valid -> calls GET /api/bootstrap to load all data
All subsequent API calls include X-User-Id header (set by Axios interceptor)
Backend reads X-User-Id from headers, defaults to 1 if missing
No JWT/session tokens -- simple header-based user identification
User : demo / demo123 (display name: "Alex Chen")
12 Dimensions : Python, JavaScript, System Design, Database, DevOps, Machine Learning, Communication, Leadership, Public Speaking, Writing, Product Thinking, Data Analysis
8 People : Alex Chen (self), Sarah Liu (mentor/North Star), James Wang (colleague), Dr. Emily Zhang (idol/North Star), Michael Tan (friend), Aisha Patel (colleague), Kevin Li (classmate), Nina Park (friend)
12 Relationships : mentor, collaborator, close, knows connections
20 Tree Nodes : System Design tree (12 nodes, 3 levels) + Python tree (8 nodes, 3 levels)
7 Time Slots : Mon-Fri 20:00-22:00, Sat 09:00-12:00, Sun 14:00-16:00
4 Schedule Blocks : CAP Theorem Review, Flask Practice, Mock Interview, REST API Notes
3 Notes : Meeting notes, Learning notes, Project idea (1 pinned)
1 Chat exchange : Demo conversation on note
1 Share token : Demo note share
Quality Scoring Algorithm
Rule-based scoring in _compute_quality_score() (app.py):
Criterion
Points
Word count >= 50
+15
Word count >= 150
+10
Word count >= 400
+10
>= 1 heading (#)
+10
>= 3 headings
+5
>= 2 code blocks
+10
>= 1 URL
+10
>= 1 reflection keyword
+10
>= 3 reflection keywords
+5
>= 3 bullet points
+10
Has blockquote (>)
+5
Max
100
Reflection keywords: reflect, lesson, insight, takeaway, realize, improve, mistake, learn
To reinitialize with fresh seed data:
rm backend/growthOS.db
cd backend && .venv/bin/python app.py
The backend auto-creates all 15 tables and seeds demo data on startup (via init_db() in db.py).
# Frontend production build
cd frontend && npm run build # outputs to frontend/dist/
# Backend (production)
cd backend && .venv/bin/python app.py # Flask dev server on :5005
Vite proxy : In dev mode, Vite proxies /api/* to http://127.0.0.1:5005. In production, configure a reverse proxy (nginx, Caddy) to route /api to Flask.
File
Lines
Purpose
backend/app.py
1,461
All API endpoints + LLM + search + RSS
backend/db.py
251
Database init + seeding
backend/schema.sql
193
15 table definitions
backend/seed_data.json
478
Demo data
frontend/src/components/NotesView.tsx
549
Largest component: editor + chat + scoring
frontend/src/components/SkillTree.tsx
506
D3 tree + list dual view
frontend/src/components/StarMap.tsx
375
D3 force graph
frontend/src/components/SketchIcons.tsx
322
33 custom SVG icons
frontend/src/components/Dashboard.tsx
314
Homepage with 7 sections
frontend/src/components/ScheduleView.tsx
237
FullCalendar + CRUD
frontend/src/components/ResourcesView.tsx
235
RSS browser
frontend/src/components/PersonCard.tsx
235
Profile card + tabs
frontend/src/index.css
219
Global styles + sketch theme
frontend/src/components/NodeDetailPanel.tsx
194
Node detail sidebar
frontend/src/types.ts
178
All TypeScript interfaces
frontend/src/components/PersonModal.tsx
158
Add/edit person form
frontend/src/api.ts
155
API client layer
frontend/src/store.ts
119
Zustand state
frontend/src/components/Login.tsx
106
Login page
frontend/src/components/Layout.tsx
102
App shell + navigation
Total
~6,900