ce439db449
主要改动: - API: 为 /api/pages 添加 lightweight 模式和分页支持 - 备份恢复: 增强 restore API 的错误处理和验证逻辑 - 工具函数: 新增 page-utils 辅助函数 - 会话管理: 优化 session 和 auth 相关逻辑 - 文档: 添加 CLAUDE.md 项目指南,包含编辑器配置注意事项 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
177 lines
5.8 KiB
Markdown
177 lines
5.8 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
NoteAI is a local knowledge note-taking application built with Next.js, Prisma (SQLite), and TipTap editor. The app provides a hierarchical page structure with rich text editing, markdown import/export, and password-protected access.
|
|
|
|
## Development Commands
|
|
|
|
```bash
|
|
# Development server (runs on port 3001)
|
|
npm run dev
|
|
|
|
# Build for production
|
|
npm run build
|
|
|
|
# Initialize environment variables
|
|
npm run env:init
|
|
|
|
# Build with environment initialization
|
|
npm run build:init
|
|
|
|
# Start production server (port 3001)
|
|
npm start
|
|
|
|
# Linting
|
|
npm run lint
|
|
|
|
# Type checking and linting together
|
|
npm run check
|
|
|
|
# Run editor block operations tests
|
|
npm test
|
|
```
|
|
|
|
## Architecture
|
|
|
|
### Database Layer (Prisma + SQLite)
|
|
|
|
- **Schema**: `prisma/schema.prisma`
|
|
- **Client**: Singleton instance in `src/lib/prisma.ts`
|
|
- **Models**:
|
|
- `Page`: Hierarchical pages with self-referential parent-child relationships. Supports both "file" and "folder" types with ordering, locking, tags, and icons.
|
|
- `GlobalSettings`: Stores scrypt-hashed password for app-wide authentication.
|
|
|
|
### State Management
|
|
|
|
- **Zustand stores** with persistence:
|
|
- `src/lib/store.ts`: Main editor state (pages, activePageId, CRUD operations)
|
|
- `src/lib/search-store.ts`: Search functionality state
|
|
- `src/lib/settings-store.ts`: Application settings state
|
|
- `src/lib/page-history.ts`: Undo/redo history management with snapshots
|
|
|
|
### Authentication & Session
|
|
|
|
- **Session management**: `src/lib/session.ts` - Custom HMAC-based session tokens stored in cookies (24h TTL)
|
|
- **Auth utilities**: `src/lib/auth.ts` - Scrypt password hashing/verification
|
|
- **API auth**: `src/lib/api-auth.ts` - Middleware for protecting API routes
|
|
- **Rate limiting**: `src/lib/rate-limit.ts` - Token bucket rate limiter for auth endpoints
|
|
|
|
### Editor System (TipTap)
|
|
|
|
- **Extensions**: Custom TipTap extensions in `src/components/editor/extensions/`
|
|
- `callout.ts` & `callout-component.tsx`: Custom callout blocks
|
|
- `ai-mark.ts`: AI-generated content marking
|
|
- `task-item.tsx`: Custom task list items
|
|
- **Block operations**: `src/lib/editor-block-ops.ts` - Core logic for moving/reordering contiguous spans of blocks (drag-and-drop support)
|
|
- **Tests**: `src/lib/editor-block-ops.test.ts` run via `scripts/run-editor-block-ops-tests.mjs`
|
|
|
|
**CRITICAL: Editor Initialization Configuration**
|
|
|
|
When modifying `src/components/editor.tsx`, preserve these critical settings for proper markdown import functionality:
|
|
|
|
```typescript
|
|
// In useEditor() configuration:
|
|
{
|
|
extensions: [
|
|
// ... other extensions
|
|
Markdown.configure({
|
|
html: true,
|
|
transformPastedText: true,
|
|
transformCopiedText: true, // MUST be true for markdown conversion
|
|
}),
|
|
],
|
|
content, // MUST pass content prop directly, NOT empty string
|
|
onUpdate: ({ editor }) => {
|
|
// ... update logic
|
|
}
|
|
}
|
|
|
|
// In useEffect for content updates:
|
|
useEffect(() => {
|
|
if (editor && content !== editor.getHTML()) {
|
|
const normalizedContent = cleanupAccidentalStandaloneInlineCode(content);
|
|
suppressNextUpdateRef.current = true;
|
|
allowOnUpdateRef.current = false;
|
|
queueMicrotask(() => {
|
|
editor.commands.setContent(normalizedContent); // Simple call, no extra options
|
|
});
|
|
if (normalizedContent !== content) {
|
|
onChange(normalizedContent);
|
|
}
|
|
}
|
|
if (editor && onEditorReady) {
|
|
onEditorReady(editor);
|
|
}
|
|
}, [content, editor, onEditorReady]); // Dependencies: do NOT include onChange
|
|
```
|
|
|
|
**Common mistakes to avoid:**
|
|
- Setting `content: ''` instead of `content` breaks markdown import display
|
|
- Setting `transformCopiedText: false` disables markdown conversion
|
|
- Adding unnecessary options to `setContent()` can cause whitespace issues
|
|
- Including `onChange` in useEffect dependencies causes infinite re-renders
|
|
|
|
### Import/Export
|
|
|
|
- **Markdown import**: `src/lib/markdown-import.ts` - Converts markdown to HTML with special handling for fenced code blocks
|
|
- **Export**: `src/lib/export.ts` - Handles exporting pages to various formats
|
|
- **File I/O**: `src/lib/file-io.ts` - File system operations for import/export
|
|
- **HTML sanitization**: `src/lib/sanitize-html.ts` - Sanitizes HTML content
|
|
|
|
### API Routes
|
|
|
|
All routes in `src/app/api/`:
|
|
- `/api/auth/login` & `/api/auth/logout`: Authentication
|
|
- `/api/settings/init`: First-time password setup (requires `INIT_SETUP_TOKEN` in production)
|
|
- `/api/settings/password`: Change password
|
|
- `/api/settings/status`: Check initialization status
|
|
- `/api/settings/restore`: Restore from backup
|
|
- `/api/pages`: CRUD operations for pages
|
|
- `/api/pages/[id]`: Individual page operations
|
|
- `/api/pages/reorder`: Batch reorder pages
|
|
- `/api/ai/chat`: AI chat integration
|
|
|
|
### Special Features
|
|
|
|
- **Wiki links**: `src/lib/wiki-links.ts` - Internal page linking system
|
|
- **Page utilities**: `src/lib/page-utils.ts` - Helper functions for page operations
|
|
- **Search**: `src/lib/search-query.ts` - Search query parsing and execution
|
|
|
|
## Environment Variables
|
|
|
|
Required in `.env`:
|
|
```env
|
|
DATABASE_URL="file:./dev.db"
|
|
SESSION_SECRET="<32+ character random string>"
|
|
INIT_DEFAULT_PASSWORD="<initial password>"
|
|
INIT_SETUP_TOKEN="<optional token for production init>"
|
|
```
|
|
|
|
## Path Aliases
|
|
|
|
- `@/*` maps to `src/*` (configured in `tsconfig.json`)
|
|
|
|
## Testing
|
|
|
|
Tests use Node's native test runner with `--experimental-strip-types` flag. Test files use `.test.ts` extension and are run via custom scripts in `scripts/` directory.
|
|
|
|
## Database Migrations
|
|
|
|
```bash
|
|
# Generate Prisma client after schema changes
|
|
npx prisma generate
|
|
|
|
# Create and apply migrations
|
|
npx prisma migrate dev
|
|
|
|
# Apply migrations in production
|
|
npx prisma migrate deploy
|
|
```
|
|
|
|
## Build Targets
|
|
|
|
Prisma is configured for both native and `linux-musl-openssl-3.0.x` targets to support Docker deployments.
|