Files
arsam 85bfafa1a1 Import documentation: PLAN.md
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
2026-09-18 23:14:14 +03:30

248 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Plan: "Notara" — A Private, Superfast, Beautifully-Crafted Notion for Windows 11
## Context
You want a **personal, single-user** Notion replacement for Windows 11 that is **fast**, **not Electron**, built on **Rust**, and — most importantly — a **real, polished, installable app** with a **guided first-run wizard** and a genuinely great experience *for you*. `START.md` catalogs the entire Notion product, but ~60% of it (SSO, SCIM, teamspaces, sharing, comments, audit logs, the public API, billing, mobile) is **multi-user/enterprise** and irrelevant here. We keep the hard, valuable core and pour the saved effort into **craft**: onboarding, microinteractions, keyboard-first flow, templates, and stability.
**Confirmed decisions:**
- **Tauri v2** — Rust backend + web UI in WebView2 (tiny binary, low RAM, not bundled Chromium).
- **All 4 pillars in v1:** block editor + page tree, databases + views, global search, deep polish.
- **Local-first, sync-ready:** SQLite on your PC now; pages stored as Yjs CRDTs so **self-hosted sync** later is plug-in, not rewrite.
- **This is a product, not a prototype:** a **first-run setup wizard**, a proper **`.msi`/`.exe` installer**, **starter templates**, **auto-backups**, a **settings screen**, and Notion-grade **microinteractions**.
**Why these tech choices (grounded in current docs):**
- **BlockNote** (`@blocknote/react`) is a Notion-style block editor on ProseMirror/TipTap — it hands us the single hardest part of any Notion clone, and is **Yjs-native**.
- **Yjs** (CRDT) is the page document format *from day one* → sync later = "attach a provider," no storage rewrite.
- **Tauri v2 SQL plugin** (SQLite + migrations) for storage; **SQLite FTS5** for instant search; **Tauri updater + bundler** for a real installer and future auto-updates.
> "GPU / superfast" reality: no hand-written shaders. Speed = Rust I/O + local SQLite + WebView2's own GPU compositing + a disciplined, virtualized frontend. This beats Notion/Electron on cold-start and RAM. A pure GPU-native editor (egui/GPUI) was rejected — it means building rich text from scratch (months–years), the wrong trade for a solo build.
---
## Architecture Overview
```
┌───────────────────────────────────────────────────────────┐
│ WebView2 (Windows built-in) — Frontend (TypeScript) │
│ │
│ React + Vite + Tailwind + Framer Motion │
│ ├─ First-run WIZARD (welcome → workspace → theme → │
│ │ templates → done) │
│ ├─ Sidebar (page tree, favorites, trash, search entry) │
│ ├─ Editor = BlockNote ⇄ Yjs (Y.Doc per page) │
│ ├─ Databases = TanStack Table/Virtual (Table/Board/...) │
│ ├─ Side-peek / center-peek for DB rows │
│ ├─ Command palette + quick-switcher (Ctrl+P / Ctrl+K) │
│ └─ Settings (theme, backups, shortcuts, about) │
│ │ @tauri-apps/api invoke() │ │
└──────────────┼────────────────────────────┼───────────────┘
▼ ▼
┌───────────────────────────────────────────────────────────┐
│ Rust core (Tauri v2) │
│ ├─ tauri-plugin-sql → SQLite (pages, blocks, dbs, FTS) │
│ ├─ tauri-plugin-fs → asset files (images, uploads) │
│ ├─ tauri-plugin-updater → future auto-updates │
│ ├─ commands → export, import, backup, heavy search │
│ └─ (LATER) yrs-based self-hosted sync server │
└───────────────────────────────────────────────────────────┘
│
▼
%APPDATA%\Notara\ → workspace.db + \assets\ + \backups\
```
---
## First-Run Setup Wizard (a headline feature)
On first launch (no `workspace.db` yet), a polished full-window wizard runs — this is the "wizard and everything" you asked for. It sets `workspace_meta.onboarded = 1` when finished so it never re-appears (re-openable from Settings → "Run setup again").
1. **Welcome** — app name, one-line pitch, animated logo; "Get started".
2. **Workspace** — name your workspace; choose data folder (default `%APPDATA%\Notara`, changeable); we create the DB + folders here.
3. **Appearance** — pick Dark / Light / System; pick accent color; font (Default/Serif/Mono). Live preview pane updates instantly.
4. **Import (optional)** — "Bring your notes": import Markdown/`.md` folder, or a Notion **Markdown+CSV export** ZIP, or start empty. Progress bar with counts.
5. **Templates** — check the starter pages/databases to seed (see gallery below), or "Empty workspace".
6. **Done** — quick 4-tip cheat sheet (slash `/`, `Ctrl+P`, drag to reorder, right-click menus) → drops you into your new home page.
**Starter templates gallery** (also reachable later via "New → From template"): Daily Journal, Tasks board (To-do/Doing/Done), Reading list (database), Meeting notes, Project tracker, Quick note. Each is just seed pages/DB rows created in SQLite.
---
## Experience & Polish Principles ("best experience")
These are first-class requirements, verified per milestone — not "nice later":
- **Keyboard-first:** command palette (`Ctrl+K`) for every action; quick-switcher (`Ctrl+P`); full editing/nav shortcut map; markdown input rules (`# `→H1, `- `→bullet, `[] `→todo).
- **Microinteractions (Framer Motion, subtle & fast, ~120–180ms):** sidebar expand/collapse, page open cross-fade, drag-and-drop **blue placement guides**, hover-revealed block handles (`+` / `⋮⋮`), toast confirmations, skeleton loaders.
- **Right-click context menus** everywhere (pages, blocks, rows): rename, duplicate, delete, move, copy link, favorite.
- **Side-peek / center-peek:** open a database row in a side panel (Notion's signature flow) without leaving the list; `Esc` closes.
- **Empty states, not blank screens:** every empty page/DB/search shows a friendly prompt + one-click action (Notion's discoverability model).
- **Native-feeling chrome:** custom title bar, window controls, remembers size/position, opens where you left off, launch-on-startup option, tray icon.
- **Instant everywhere:** virtualized lists (TanStack Virtual) so a 5,000-row database and a 1,000-page sidebar stay smooth.
- **Zero data loss:** debounced autosave + crash-safe Yjs persistence + rolling local backups.
---
## Visual Fidelity — an *exact*, modern Notion-like interface
A hard goal: someone glancing at the screen should read it as Notion. We replicate Notion's actual layout, spacing, type, and color system (a clean-room rebuild of the *look & feel* — our own code/assets, no copied proprietary files):
- **Overall layout:** left **sidebar** (~240px, resizable, collapsible with `<<`) + main content area; centered page column (**~708px content width**, "Full width" toggle expands it); generous whitespace, calm density.
- **Sidebar look:** subtle gray background, small uppercase section labels (Favorites / Private / Shared), page rows with emoji/icon + title, hover-revealed `+` and `⋮` (`•••`) controls, disclosure triangles for nesting, drag handles. Workspace switcher at top, Search + Settings + Trash near it.
- **Typography:** Notion uses a system UI stack (Inter-like sans) — ship **Inter** as the default, plus **Serif (Lyon-like → Georgia/serif)** and **Mono** page styles; heading sizes and line-heights matched to Notion (H1 ~1.875rem, body ~16px, ~1.5 line-height); "Small text" and "Full width" page toggles.
- **Color system (CSS variables, light + dark):** near-white `#ffffff` / dark `#191919` backgrounds, `#37352f` text on light / `#e9e9e7` on dark, Notion's exact block highlight palette (gray/brown/orange/yellow/green/blue/purple/pink/red for text + backgrounds), `#2383e2`-style blue accents and selection.
- **Editor chrome:** hover **block handle** (`⋮⋮` drag + `+` insert) in the left gutter, `/` **slash menu** styled like Notion's (grouped, icons, search), the **bubble/selection toolbar** (B/I/U/S, code, link, color), placeholder text ("Type '/' for commands"), the "Press Enter to continue" empty-line feel.
- **Page header:** hover-revealed **Add icon / Add cover / Add comment** row, large title, breadcrumb bar up top, `Share`-less (private) but with `•••` menu (style, small text, full width, export, move to trash) and updates/history.
- **Database chrome:** view tabs row with `+ New view`, right-aligned Filter/Sort/Search/`•••`/blue **New** button; table with resizable/reorderable columns, property-type icons, row hover `⋮⋮`, the blue **`+ New`** row; Board columns with count badges.
- **Icons:** Lucide chosen to match Notion's line-icon weight; emoji picker for page icons like Notion.
We'll tune this against Notion side-by-side (screenshots from `START.md`'s UI/UX spec) each milestone until it reads as a match. Fidelity is a **verification item**, not an afterthought.
---
## Tech Stack (pinned)
| Layer | Choice | Why |
|---|---|---|
| Shell | **Tauri v2** (+ updater + bundler) | Rust, WebView2, ~10MB, real installer |
| Backend | **Rust** | Speed; `yrs` for future sync |
| Frontend | **React 18 + TypeScript + Vite** | BlockNote is React; best ecosystem for a novice |
| Editor | **BlockNote** (`@blocknote/react`, `/core`) | Notion-style, Yjs-native |
| Doc format | **Yjs** | CRDT → sync-ready day one |
| Styling | **Tailwind CSS** + CSS vars | Theming (dark/light/accent) |
| Motion | **Framer Motion** | Polished, restrained animations |
| DB grids | **TanStack Table + Virtual** | Fast virtualized database views |
| App state | **Zustand** | Tiny client state |
| Storage | **SQLite** via `tauri-plugin-sql` (+FTS5) | Local, instant, migrations |
| Assets/backup | `tauri-plugin-fs` | Images/uploads + backup files |
| Icons | **Lucide** | Clean, Notion-like |
---
## Data Model (SQLite)
Structured metadata in relational tables; **page bodies as Yjs binary blobs** (editor's source of truth) — keeps tree/search/DB queries fast while keeping rich text conflict-free and sync-ready.
```sql
CREATE TABLE workspace_meta ( -- single row: name, data_dir, theme, accent, onboarded, last_page
id INTEGER PRIMARY KEY CHECK (id=1), name TEXT, theme TEXT, accent TEXT,
onboarded INTEGER DEFAULT 0, last_page_id TEXT, settings JSON
);
CREATE TABLE pages (
id TEXT PRIMARY KEY, parent_id TEXT REFERENCES pages(id),
title TEXT DEFAULT '', icon TEXT, cover TEXT,
sort_order REAL, is_favorite INTEGER DEFAULT 0, in_trash INTEGER DEFAULT 0,
created_at INTEGER, updated_at INTEGER
);
CREATE TABLE page_docs ( page_id TEXT PRIMARY KEY REFERENCES pages(id), ydoc BLOB );
CREATE TABLE databases ( id TEXT PRIMARY KEY, page_id TEXT, name TEXT );
CREATE TABLE db_properties ( id TEXT PRIMARY KEY, database_id TEXT, name TEXT, type TEXT, config JSON, sort_order REAL );
CREATE TABLE db_rows ( id TEXT PRIMARY KEY, database_id TEXT, page_id TEXT REFERENCES pages(id), sort_order REAL );
CREATE TABLE db_values ( row_id TEXT, property_id TEXT, value JSON, PRIMARY KEY(row_id, property_id) );
CREATE TABLE db_views ( id TEXT PRIMARY KEY, database_id TEXT, name TEXT, type TEXT,
filters JSON, sorts JSON, groups JSON, visible_props JSON, sort_order REAL );
CREATE VIRTUAL TABLE pages_fts USING fts5(page_id UNINDEXED, title, body);
```
- **Fractional `sort_order`** → drag-reorder is a one-row update.
- **DB rows are pages** (Notion's model) → reuse the editor + `page_docs` for row bodies.
- **FTS mirror** updated on save from the Y.Doc's plain text → instant search.
---
## Phased Roadmap
Ships a usable app early, then layers craft. Each milestone runs and is verified independently.
### Milestone 0 — Environment, scaffold, installer skeleton (1 day)
- Install prerequisites (below). Scaffold `create-tauri-app` (React+TS+Vite). Wire Tailwind, Zustand, Framer Motion, Lucide.
- Add `tauri-plugin-sql`+`tauri-plugin-fs`; first migration creates all tables. Custom title bar + window state persistence.
- Confirm `npm run tauri build` produces a working **`.msi`/`.exe`** you can install. Create project **`PLAN.md`** (this file).
### Milestone 1 — First-run wizard + pages + block editor (the core) (2 weeks)
- **The wizard** (all 6 steps above), gated on `workspace_meta.onboarded`.
- Sidebar tree: create/rename/delete, **drag-reorder & nest** with blue guides, favorites, trash + restore, right-click menus.
- Editor: **BlockNote** bound to a per-page **Y.Doc**; debounced persist to `page_docs` + FTS mirror; page header (title, emoji icon, cover).
- Starter templates seeding.
- **Outcome:** a real, private note app with onboarding you'd use daily.
### Milestone 2 — Search + command palette (3–4 days)
- `Ctrl+P` quick-switcher; `Ctrl+K` command palette (all actions); FTS full-text search, instant + keyboard-navigable; empty/no-result states.
### Milestone 3 — Databases & views (3–4 weeks; second pillar)
- Inline & full-page databases; property types: text, number, select, multi-select, status, date, checkbox, URL, created/edited time.
- Views: **Table** (TanStack Table+Virtual), **Board** (group-by), **List**, **Gallery**, **Calendar**; per-view filters/sorts/groups/column-visibility.
- **Side-peek** row → full page editor (reuses M1). Row context menus.
### Milestone 4 — Deep polish, settings, backups, export/import (2 weeks)
- **Settings screen:** appearance (theme/accent/font), backups, shortcuts reference, data folder, launch-on-startup, "run setup again", about/version.
- Dark/light/system + accent theming; finalize all shortcuts & markdown rules; motion pass.
- **Auto-backups:** rolling timestamped copies of `workspace.db` to `\backups\` (on close + interval); restore-from-backup UI.
- **Export:** page/workspace → Markdown & HTML (Rust command); PDF via WebView print. **Import:** Markdown folder + Notion export ZIP (also used in wizard).
- Tray icon, launch-on-startup, remembers last page.
### Milestone 5 (LATER, optional) — Self-hosted sync + auto-update
- Pages are already Yjs → add a client **provider** + small **`yrs`** (Rust) self-hosted server, single shared secret. Wire **`tauri-plugin-updater`** for one-click app updates. No data-model change.
---
## Proposed Directory Structure
```
D:\Projects\Notion\
├─ PLAN.md
├─ package.json vite.config.ts index.html
├─ src\ # FRONTEND
│ ├─ main.tsx App.tsx
│ ├─ wizard\ # first-run onboarding steps + templates
│ ├─ store\ # Zustand: workspace, ui, theme
│ ├─ db\ # TS data layer over sql plugin / invoke()
│ ├─ editor\ # BlockNote + Yjs binding + persistence hook
│ ├─ sidebar\ # page tree, drag-reorder, context menus
│ ├─ database\ # views: table/board/calendar/gallery/list + peek
│ ├─ search\ # quick-switcher + command palette + FTS
│ ├─ settings\ # settings screen, backups UI
│ └─ components\ # title bar, menus, modals, toasts, empty states
└─ src-tauri\ # BACKEND (Rust)
├─ Cargo.toml tauri.conf.json
├─ migrations\0001_init.sql
└─ src\ lib.rs main.rs commands\ (export, import, backup, search)
```
**First files (M0–M1):** `src-tauri/src/lib.rs` (plugin init + migrations), `migrations/0001_init.sql`, `src/db/index.ts` (typed helpers), `src/editor/useYjsPage.ts` (load blob→hydrate Y.Doc→bind BlockNote→debounced persist+FTS), `src/wizard/Wizard.tsx`, `src/App.tsx`, custom `TitleBar.tsx`.
---
## Prerequisites (Milestone 0 — you run these; prefix with `!` in the session or use a terminal)
1. **Rust** via `rustup` (https://rustup.rs). 2. **Node.js LTS v20+**. 3. **Microsoft C++ Build Tools** (MSVC). 4. **WebView2 Runtime** (preinstalled on Win11 — verify). The Tauri bundler produces the `.msi`; WebView2 is auto-bootstrapped in the installer.
---
## Verification (per milestone — prove it actually works)
- **M0:** `tauri dev` opens; SQLite insert/read round-trips; `tauri build` yields an `.msi` that **installs and launches**; custom title bar drags/resizes.
- **M1:** Fresh profile → **wizard runs end-to-end**, seeds templates, never reappears. Create nested pages, drag-reorder, rich blocks; **close & reopen → content persists**; kill mid-edit → no loss.
- **M2:** ~50 pages: `Ctrl+P` and search return correct results <50ms; `Ctrl+K` runs actions.
- **M3:** DB with 3–4 property types; switch Table↔Board↔Calendar; filter/sort/group; **side-peek** a row and edit its body.
- **M4:** Toggle theme/accent live; export a tree to Markdown and diff; trigger a backup and **restore** it; import a Markdown folder.
- **Perf throughout:** cold-start & idle RAM measured vs. Notion (expect large wins); 1k-page sidebar + 5k-row DB stay smooth.
- **Fidelity throughout:** side-by-side against real Notion screenshots each milestone — sidebar, page column width, type scale, color/highlight palette, block handles, slash menu, and database chrome must read as a visual match.
---
## Risks & Mitigations
- **Scope:** dropped all multi-user/enterprise; strict phasing; M1 alone is usable.
- **Databases (biggest sub-project):** isolated to M3; can ship M1–M2 and live in it first.
- **Yjs persistence:** start with full-state blob per page (simple/correct); move to incremental updates only if a page grows large.
- **Rust curve:** most logic is TypeScript; Rust ≈ plugin config + a few export/import/backup commands.
- **Polish creep:** motion/interaction budget fixed (fast, subtle) so it never balloons.
---
## What comes first when building starts
1. Scaffold Tauri v2 + React + TS; custom title bar; confirm it launches **and** builds an installer.
2. Wire SQLite migrations + the M1 wizard/editor/sidebar skeleton.
3. (Interactive installs of Rust/Node/Build Tools are run by you with `!`.)