| 协议 | 认证方式 | 说明 |
|------|----------|------|
| Gmail API | OAuth2 | 需要 Google Cloud 项目 |
| IMAP | SSL/TLS | 传统邮箱协议 |
| Microsoft Graph | OAuth2 | Outlook/Office365 |

**凭证配置(预留)**:

# config.yaml
email:
  provider: gmail  # gmail | imap | microsoft
  gmail:
    client_id_env: GMAIL_CLIENT_ID
    client_secret_env: GMAIL_CLIENT_SECRET
  imap:
    server: imap.example.com
    port: 993
    username_env: IMAP_USERNAME
    password_env: IMAP_PASSWORD


---

## 12. 配置

### 12.1 配置文件示例


# ~/.config/synapse/config.yaml

workspace: ~/synapse-data
default_namespace: personal

namespaces:
  - personal      # 1
  - work-project  # 2
  - study         # 3

editor:
  windows: { default: notepad, options: [notepad, typora, code] }
  linux: { default: vim, options: [vim, typora] }
  macos: { default: vim, options: [vim, typora] }

git:
  auto_commit: true
  commit_style: conventional  # conventional | simple | llm
  llm:
    enabled: false
    provider: litellm
    model: gpt-4o-mini
    api_base: https://api.openai.com/v1
    api_key_env: OPENAI_API_KEY
  remotes:
    - name: origin
      url: [email protected]:user/synapse-data.git
      auto_push: true

johnny_decimal:
  areas:
    00: "Inbox"
    10: "个人管理"
    20: "工作项目"
    30: "学习成长"

review:
  daily_time: "08:00"
  weekly_day: friday
  weekly_time: "18:00"


---

## 13. 性能与索引机制

### 13.1 性能目标

| 操作 | 目标 | 实现方式 |
|------|------|----------|
| 列表 10,000 资源 | < 500ms | SQLite 索引 |
| 全文搜索 | < 1s | Ripgrep |
| 创建/更新 | < 300ms | 增量索引更新 |

### 13.2 SQLite Sidecar Index

**问题**:10,000 个 Markdown 文件逐个解析 Frontmatter,IO 开销巨大。

**方案**:`.synapse/index.db` 缓存所有元数据。


-- 主索引表
CREATE TABLE resources (
    id TEXT PRIMARY KEY,        -- "10.001.0015"
    namespace TEXT,
    area TEXT,                  -- "10"
    category TEXT,              -- "001"
    type TEXT,
    title TEXT,
    status TEXT,
    priority TEXT,
    due DATE,
    created DATETIME,
    modified DATETIME,
    tags TEXT,                  -- JSON array
    content_hash TEXT,          -- 用于变更检测
    file_path TEXT
);

-- 全文搜索 (FTS5) - 存储预分词后的内容
CREATE VIRTUAL TABLE resources_fts USING fts5(
    id, title_tokens, tags_tokens, content_tokens,
    tokenize = 'simple'  -- 使用默认分词器,输入已分词字符串
);


**中文搜索:应用层分词方案**(推荐)

SQLite 原生不支持加载 Python jieba 作为分词器。最佳实践是**应用层分词**:


import jieba
import re

# 停用词表(标点、空格、无意义字符)
STOPWORDS = set(['的', '了', '是', '在', '我', '有', '和', '就', 
                  '不', '人', '都', '一', '一个', '上', '也', '很',
                  '到', '说', '要', '去', '你', '会', '着', '没有'])

class SearchEngine:
    def _tokenize(self, text: str) -> str:
        """分词 + 停用词过滤 + 标点清理"""
        # 1. 移除标点符号和特殊字符
        text = re.sub(r'[^\w\s\u4e00-\u9fff]', ' ', text)
        
        # 2. jieba 分词
        tokens = jieba.cut_for_search(text)
        
        # 3. 停用词过滤 + 去除空白
        filtered = [t.strip() for t in tokens 
                    if t.strip() and t not in STOPWORDS]
        
        return " ".join(filtered)
    
    def update_index(self, id: str, title: str, content: str):
        """写入索引前,用 jieba 预处理 + 停用词过滤"""
        title_tokens = self._tokenize(title)
        content_tokens = self._tokenize(content)
        
        cursor.execute("""
            INSERT INTO resources_fts (id, title_tokens, content_tokens) 
            VALUES (?, ?, ?)
        """, (id, title_tokens, content_tokens))
    
    def search(self, query: str):
        """搜索时,同样分词处理"""
        query_tokens = " AND ".join(self._tokenize(query).split())
        
        cursor.execute("""
            SELECT id FROM resources_fts 
            WHERE content_tokens MATCH ?
        """, (query_tokens,))


**停用词过滤的好处**:
- 减小 index.db 体积(去除 30%+ 无意义词)
- 提高搜索精度(避免"的"、"了"等高频词干扰)
- 加快搜索速度

**工作流程**:
- **写入**:"完成了需求设计!" → 清理标点 → jieba → 过滤停用词 → "完成 需求 设计" → 存入 FTS
- **搜索**:用户搜 "需求" → 同样处理 → "需求" → MATCH 成功

### 13.3 索引更新策略

| 触发时机 | 动作 |
|----------|------|
| syn 启动 | 检测 Git 变更,增量更新索引 |
| CRUD 操作 | 实时更新索引 |
| Git hook | post-merge, post-checkout 触发重建 |
| 手动 | syn index rebuild 强制重建 |

### 13.4 查询路由
 
 
Back to Top