增加API分页和轻量级查询支持,完善备份恢复功能
主要改动: - API: 为 /api/pages 添加 lightweight 模式和分页支持 - 备份恢复: 增强 restore API 的错误处理和验证逻辑 - 工具函数: 新增 page-utils 辅助函数 - 会话管理: 优化 session 和 auth 相关逻辑 - 文档: 添加 CLAUDE.md 项目指南,包含编辑器配置注意事项 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user