- Add separate momentry_playground binary with distinct configuration - Production (momentry): Port 3002, Redis prefix 'momentry:' - Development (momentry_playground): Port 3003, Redis prefix 'momentry_dev:' - Add SERVER_PORT and REDIS_KEY_PREFIX config via environment variables - Replace all hardcoded Redis key prefixes with configurable values - Create .env.development for playground environment settings - Update .env with production defaults - Add dotenv dependency for environment file loading Configuration isolation allows running both binaries simultaneously without port conflicts or Redis key collisions.
414 lines
11 KiB
Markdown
414 lines
11 KiB
Markdown
# AGENTS.md - Momentry Core
|
||
|
||
Rust-based digital asset management system with video analysis and RAG capabilities.
|
||
|
||
## Build & Run Commands
|
||
|
||
```bash
|
||
# Build project
|
||
cargo build
|
||
cargo build --release
|
||
cargo build --bin momentry
|
||
cargo build --bin momentry_playground
|
||
|
||
# Build all binaries
|
||
cargo build --bins
|
||
|
||
# Run CLI
|
||
cargo run -- --help
|
||
cargo run -- register /path/to/video.mp4
|
||
cargo run -- server --host 0.0.0.0 --port 3002
|
||
|
||
# Run playground (development binary)
|
||
cargo run --bin momentry_playground -- server
|
||
cargo run --bin momentry_playground -- --help
|
||
```
|
||
|
||
## Binaries
|
||
|
||
| Binary | Purpose | Port | Redis Prefix | Environment |
|
||
|--------|---------|------|--------------|-------------|
|
||
| `momentry` | Production | 3002 | `momentry:` | `.env` |
|
||
| `momentry_playground` | Development | 3003 | `momentry_dev:` | `.env.development` |
|
||
| `momentry_player` | Video player | - | - | - |
|
||
|
||
## Testing
|
||
|
||
```bash
|
||
# Run all tests
|
||
cargo test
|
||
|
||
# Run single test by name
|
||
cargo test test_name
|
||
|
||
# Run with output
|
||
cargo test -- --nocapture
|
||
|
||
# Doc tests
|
||
cargo test --doc
|
||
```
|
||
|
||
## Linting & Formatting
|
||
|
||
```bash
|
||
# Format code (edition=2021, max_width=100, tab_spaces=4)
|
||
cargo fmt
|
||
cargo fmt -- --check
|
||
|
||
# Lint
|
||
cargo clippy
|
||
cargo clippy --all-features
|
||
|
||
# Check for errors
|
||
cargo check
|
||
cargo check --all-features
|
||
```
|
||
|
||
## Code Style
|
||
|
||
### General
|
||
- Use Rust 2021 edition
|
||
- Use tracing for logging (not println!)
|
||
- Keep lines under 100 characters
|
||
|
||
### Imports (order: std → external → local)
|
||
```rust
|
||
use std::path::Path;
|
||
use anyhow::{Context, Result};
|
||
use async_trait::async_trait;
|
||
use serde::{Deserialize, Serialize};
|
||
|
||
use crate::core::chunk::Chunk;
|
||
```
|
||
|
||
### Error Handling
|
||
- Use `anyhow::Result<T>` for application code
|
||
- Use `thiserror` for library code
|
||
- Use `.context()` for error context
|
||
- Use `anyhow::bail!()` for early returns
|
||
|
||
```rust
|
||
fn example() -> Result<SomeType> {
|
||
let output = Command::new("ffprobe")
|
||
.args([...])
|
||
.output()
|
||
.context("Failed to run ffprobe")?;
|
||
|
||
if !output.status.success() {
|
||
anyhow::bail!("Command failed");
|
||
}
|
||
Ok(result)
|
||
}
|
||
```
|
||
|
||
### Naming
|
||
- Types/Enums: PascalCase (`VideoRecord`, `ChunkType`)
|
||
- Functions/Variables: snake_case (`get_video_by_uuid`)
|
||
- Traits: PascalCase with -er suffix (`Database`, `ChunkStore`)
|
||
- Files: snake_case (`postgres_db.rs`)
|
||
|
||
### Types
|
||
- Use `serde::{Deserialize, Serialize}` for serializable types
|
||
- Use `#[serde(rename_all = "snake_case")]` for enum variants
|
||
- Use explicit numeric types (i64, u32, f64)
|
||
|
||
```rust
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct VideoRecord {
|
||
pub id: i64,
|
||
pub uuid: String,
|
||
pub duration: f64,
|
||
pub width: u32,
|
||
}
|
||
|
||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
|
||
#[serde(rename_all = "snake_case")]
|
||
pub enum ChunkType {
|
||
TimeBased,
|
||
Sentence,
|
||
Cut,
|
||
}
|
||
```
|
||
|
||
### Async Programming
|
||
- Use `tokio` runtime with full features
|
||
- Use `#[async_trait]` for async trait methods
|
||
|
||
```rust
|
||
#[async_trait]
|
||
pub trait Database: Send + Sync {
|
||
async fn init() -> Result<Self>
|
||
where Self: Sized;
|
||
}
|
||
```
|
||
|
||
## Code Structure
|
||
|
||
```
|
||
src/
|
||
├── main.rs # CLI entry point
|
||
├── lib.rs # Library exports
|
||
├── core/
|
||
│ ├── api_key/ # API key management (anomaly, blacklist, encryption, etc.)
|
||
│ ├── chunk/ # Chunking logic
|
||
│ ├── config.rs # Centralized configuration (env vars)
|
||
│ ├── db/ # Database (PostgreSQL, MongoDB, Redis, Qdrant)
|
||
│ ├── embedding/ # Vector embeddings
|
||
│ ├── overlay/ # Video overlay
|
||
│ ├── probe/ # ffprobe integration
|
||
│ ├── processor/ # ASR, OCR, YOLO, Face, Pose, CUT, ASRX
|
||
│ │ └── executor.rs # Unified Python script executor
|
||
│ ├── storage/ # File management
|
||
│ └── thumbnail/ # Thumbnail extraction
|
||
├── api/ # HTTP API (axum)
|
||
├── player/ # Video player
|
||
├── ui/ # TUI components
|
||
└── watcher/ # File system watcher
|
||
```
|
||
|
||
## Key Dependencies
|
||
|
||
- **Error handling**: `anyhow`, `thiserror`
|
||
- **Async**: `tokio` (full features), `async-trait`
|
||
- **CLI**: `clap` (derive)
|
||
- **Serialization**: `serde`, `serde_json`, `chrono`
|
||
- **Database**: `sqlx`, `mongodb`, `redis` (1.0), `qdrant-client`
|
||
- **HTTP**: `axum`, `tower`
|
||
- **Logging**: `tracing`, `tracing-subscriber`
|
||
- **Config**: `once_cell` (lazy static config)
|
||
|
||
## Environment Variables
|
||
|
||
### Server
|
||
- `MOMENTRY_SERVER_PORT` - API server port (default: `3002` for production, `3003` for playground)
|
||
- `MOMENTRY_REDIS_PREFIX` - Redis key prefix (default: `momentry:` for production, `momentry_dev:` for playground)
|
||
|
||
### Database
|
||
- `DATABASE_URL` - PostgreSQL (default: `postgres://accusys@localhost:5432/momentry`)
|
||
|
||
### Redis
|
||
- `REDIS_URL` - Redis URL (default: `redis://:accusys@localhost:6379`)
|
||
- `REDIS_PASSWORD` - Redis password (default: `accusys`)
|
||
|
||
### Paths
|
||
- `MOMENTRY_OUTPUT_DIR` - Output directory (default: `/Users/accusys/momentry/output`)
|
||
- `MOMENTRY_BACKUP_DIR` - Backup directory
|
||
- `MOMENTRY_PYTHON_PATH` - Python path (default: `/opt/homebrew/bin/python3.11`)
|
||
- `MOMENTRY_SCRIPTS_DIR` - Scripts directory
|
||
|
||
### Processor Timeouts
|
||
- `MOMENTRY_ASR_TIMEOUT` - ASR timeout in seconds (default: 3600)
|
||
- `MOMENTRY_CUT_TIMEOUT` - CUT timeout in seconds (default: 3600)
|
||
- `MOMENTRY_DEFAULT_TIMEOUT` - Default timeout (default: 7200)
|
||
|
||
### Logging
|
||
- `RUST_LOG` or `MOMENTRY_LOG_LEVEL` - Log level (default: `info`)
|
||
|
||
## Notes
|
||
|
||
- Unit tests exist (86 library tests)
|
||
- Video processing uses external tools (ffprobe, Python scripts)
|
||
- Multi-database architecture (PostgreSQL, MongoDB, Redis, Qdrant)
|
||
- Monitor directory is a separate system (not Rust)
|
||
- PythonExecutor provides unified script execution with timeout support
|
||
- Redis 1.0.x for improved performance
|
||
|
||
## Task Management
|
||
|
||
### 使用 todowrite 追蹤任務
|
||
```bash
|
||
# 創建任務清單
|
||
/todo 建立配置模組 [in_progress]
|
||
/todo 添加單元測試 [pending]
|
||
|
||
# 更新狀態
|
||
/todo 完成標記 [completed]
|
||
```
|
||
|
||
### 任務批次建議
|
||
- 一次處理 1-2 個功能
|
||
- 每個功能完成後驗證 (clippy + test)
|
||
- 驗證通過後再繼續下一個
|
||
|
||
## Code Review Checklist
|
||
|
||
完成任務後檢查:
|
||
- [ ] `cargo clippy --lib` 通過
|
||
- [ ] `cargo test --lib` 通過
|
||
- [ ] `cargo fmt -- --check` 通過
|
||
- [ ] 文檔已更新 (如需要)
|
||
- [ ] 新功能有單元測試
|
||
|
||
## Commit Guidelines
|
||
|
||
```bash
|
||
# feat: 新功能
|
||
git commit -m "feat: add monitor_jobs table"
|
||
|
||
# fix: 錯誤修復
|
||
git commit -m "fix: resolve SQL injection in store_vector"
|
||
|
||
# refactor: 重構
|
||
git commit -m "refactor: use parameterized queries"
|
||
|
||
# docs: 文檔更新
|
||
git commit -m "docs: update AGENTS.md with new modules"
|
||
```
|
||
|
||
## Pre-commit Hook
|
||
|
||
專案已配置 `.git/hooks/pre-commit`,提交前自動檢查:
|
||
|
||
```bash
|
||
# 檢查內容
|
||
1. cargo fmt --check # Rust 格式化檢查
|
||
2. cargo clippy --lib # Rust Lint 檢查
|
||
3. cargo test --lib # Rust 單元測試
|
||
4. ruff check # Python Lint 檢查
|
||
5. ruff format --check # Python 格式化檢查
|
||
6. markdownlint # Markdown 格式檢查
|
||
7. shellcheck # Shell 腳本檢查
|
||
|
||
# 跳過檢查(不建議)
|
||
git commit --no-verify
|
||
|
||
# 跳過特定檢查
|
||
git commit --skip-checks
|
||
```
|
||
|
||
**注意**: Hook 僅檢查已暫存的 Rust/Python/Markdown 文件。
|
||
|
||
### Python 環境設置
|
||
```bash
|
||
# 安裝 ruff
|
||
pip install ruff==0.11.2
|
||
|
||
# 格式化 Python 文件
|
||
ruff format scripts/
|
||
|
||
# Lint Python 文件
|
||
ruff check scripts/
|
||
```
|
||
|
||
### Markdown 環境設置
|
||
```bash
|
||
# 安裝 markdownlint-cli (使用系統 Node.js)
|
||
npm install -g markdownlint-cli
|
||
|
||
# 檢查 Markdown 文件
|
||
markdownlint docs/
|
||
|
||
# 配置檔案
|
||
.markdownlint.json
|
||
```
|
||
|
||
### Shell 環境設置
|
||
```bash
|
||
# 安裝 shellcheck
|
||
brew install shellcheck
|
||
|
||
# 檢查 Shell 腳本
|
||
shellcheck scripts/*.sh monitor/**/*.sh
|
||
```
|
||
|
||
**注意**: Hook 只檢查 error 等級的 shellcheck 問題,style 警告會顯示但不阻擋提交。
|
||
|
||
## Reference Documents
|
||
|
||
| 文件 | 用途 |
|
||
|------|------|
|
||
| `docs/OPENCODE_GUIDE.md` | OpenCode 使用規範 |
|
||
| `docs/ARCHITECTURE_EVALUATION.md` | 架構優化待評估項目 (含 GraphRAG) |
|
||
| `docs/PENDING_ISSUES.md` | 待解決問題追蹤 |
|
||
| `docs/MOMENTRY_CORE_MONITORING.md` | 監控系統規範 |
|
||
| `docs/MOMENTRY_CORE_REDIS_KEYS.md` | Redis Key 設計規範 |
|
||
| `docs/PYTHON.md` | Python 腳本規範 |
|
||
| `docs/FILE_CHANGE_MANAGEMENT.md` | 文件修改管理規範 |
|
||
| `docs/YOLO_RESUME_INTEGRATION.md` | YOLO Resume 功能整合記錄 |
|
||
| `docs/DOCUMENT_EMBEDDING_STRATEGY.md` | Parent-Child 嵌入策略 |
|
||
| `docs/PROCESSING_PIPELINE.md` | 處理流程文檔 |
|
||
| `docs/N8N_DEMO_WORKFLOW.md` | n8n 工作流文檔 |
|
||
| `docs/FRESH_MAC_INSTALLATION.md` | 全新 Mac 安裝指南 |
|
||
| `docs/SERVICES.md` | 服務總覽與管理 |
|
||
| `docs/SFTPGO_DEMO_USER.md` | SFTPGo 用戶指南 |
|
||
|
||
## Document Change Workflow
|
||
|
||
修改文件前請參考 `docs/FILE_CHANGE_MANAGEMENT.md`,確保:
|
||
|
||
1. **修改前**:完整閱讀文件、執行預檢清單
|
||
2. **修改中**:提供變更計畫、取得確認
|
||
3. **修改後**:展示 diff、更新版本歷史
|
||
4. **驗證**:執行 lint/test、提交前審查
|
||
|
||
### AI 工具修改規範
|
||
|
||
AI 工具修改文件時:
|
||
- 必須先完整閱讀文件(不可只讀取部分章節)
|
||
- 修改前先提出變更計畫供確認
|
||
- 修改後展示 diff 內容
|
||
- 更新版本歷史表
|
||
|
||
## PHP Development
|
||
|
||
WordPress 作為 Momentry Portal,負責 n8n 自動化與 sftpgo 檔案服務的頁面整合。
|
||
|
||
### 編輯器設定
|
||
|
||
| 編輯器 | LSP 方案 | 安裝方式 |
|
||
|--------|----------|----------|
|
||
| VS Code | Intelephense | Extension Marketplace (推薦) |
|
||
| Cursor | Intelephense | Extension Marketplace (推薦) |
|
||
| CLI | phpactor | `~/bin/phpactor` |
|
||
|
||
### Intelephense (VS Code/Cursor)
|
||
|
||
1. 安裝 Extension: 搜尋 "Intelephense"
|
||
2. 設定:
|
||
```json
|
||
{
|
||
"intelephense.stubs": ["wordpress"]
|
||
}
|
||
```
|
||
|
||
### phpactor (CLI)
|
||
|
||
```bash
|
||
# 安裝方式
|
||
brew install composer
|
||
curl -sSL https://github.com/phpactor/phpactor/releases/latest/download/phpactor.phar -o ~/bin/phpactor
|
||
chmod +x ~/bin/phpactor
|
||
|
||
# 安裝 WordPress Stubs
|
||
cd /Users/accusys/wordpress/web
|
||
composer require --dev php-stubs/wordpress-stubs
|
||
|
||
# 建立 WordPress 索引
|
||
cd /Users/accusys/wordpress/web
|
||
~/bin/phpactor index:build --reset
|
||
|
||
# 常用指令
|
||
~/bin/phpactor class:search "WP_User" # 搜尋類別
|
||
~/bin/phpactor index:query WP_User # 查看類別資訊
|
||
~/bin/phpactor navigate /path/to/file.php # 導航到定義
|
||
```
|
||
|
||
### WordPress 程式碼位置
|
||
| 類型 | 路徑 |
|
||
|------|------|
|
||
| 主題 | `/Users/accusys/wordpress/web/wp-content/themes/` |
|
||
| 插件 | `/Users/accusys/wordpress/web/wp-content/plugins/` |
|
||
|
||
### 與 marcom 團隊協作
|
||
| 角色 | 負責 |
|
||
|------|------|
|
||
| marcom 團隊 | Figma 設計 / Elementor 建構 |
|
||
| OpenCode | 程式碼實作 / 重構 |
|
||
|
||
### 開發時程
|
||
```
|
||
Phase 1: marcom 建構 (現在) → Elementor 頁面建構
|
||
Phase 2: 交付審視 (TBD) → 功能確認 / 重構評估
|
||
Phase 3: OpenCode 重構 → 純程式碼實作,交付無 Elementor 依賴版本
|
||
```
|