一键导入
review-flagged
Interactively review flagged transactions to confirm or correct categorizations, and create rules based on user feedback.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Interactively review flagged transactions to confirm or correct categorizations, and create rules based on user feedback.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Process large volumes of bank statements (50+ PDFs) in batches with checkpointing and progress tracking. Orchestrates the standard ingestion skill across multiple batches for resumable processing.
Categorize financial transactions by analyzing merchant names, amounts, and context. Assigns spending categories with confidence scores and suggests pattern rules. Use when you need to categorize transactions or determine spending patterns.
Parse bank statement CSV files into structured transaction data. Extracts account information and transactions from CSV exports. Use when you need to process CSV bank statements.
Extract transactions from PDF or CSV bank statements in the staging folder, categorize them using Claude AI, insert into database, and archive processed files. Use when you need to ingest, process, or import new bank statements (PDF or CSV format).
Manage transaction memory to view patterns, add quick notes, search for merchants, and clean up outdated entries. Use when you need to check what's in memory, add new learnings, or maintain the memory file.
Parse bank statement PDF text into structured transaction data with account information and transactions in consistent JSON format. Works with any bank format. Use when you need to extract or parse transactions from PDF bank statements.
| name | review-flagged |
| description | Interactively review flagged transactions to confirm or correct categorizations, and create rules based on user feedback. |
Present flagged transactions (low confidence < 0.7) to the user for review, accept corrections, and create categorization rules based on confirmed patterns. This skill enables the system to learn from user feedback and improve categorization accuracy over time.
Important: When executing this skill within Claude Code, use the AskUserQuestion tool to interact with the user, not the scripts/review_flagged.py script (which is for standalone CLI use).
Use the AskUserQuestion tool to present transactions and collect user feedback:
Run scripts/review_flagged.py for command-line interactive review:
uv run python scripts/review_flagged.py [--log-id <id>]
This provides a full-featured CLI with rule creation options.
Query database for all flagged transactions:
from src.database.models import Database
from src.config import get_config
config = get_config()
db = Database(config['database_path'])
flagged = db.get_flagged_transactions()
if not flagged:
print("No flagged transactions to review.")
exit(0)
print(f"\n📋 Found {len(flagged)} flagged transaction(s) to review\n")
When using Claude Code, use the AskUserQuestion tool to present transactions:
from src.database.models import Database
from src.config import get_config
# Prepare transaction details for display
for txn in flagged:
merchant = txn.merchant_cleaned or txn.merchant_original
# Use AskUserQuestion tool with structured options
questions = [{
"question": f"Transaction: {merchant} (${abs(txn.amount):.2f}) on {txn.transaction_date}\nSuggested category: {txn.category}\nConfidence: {txn.confidence_score or 0:.2f}\n\nWhat would you like to do?",
"header": "Review",
"multiSelect": False,
"options": [
{
"label": f"Accept as {txn.category}",
"description": f"Keep the suggested category ({txn.category})"
},
{
"label": "Change category",
"description": "Select a different category from the list"
},
{
"label": "Skip for now",
"description": "Leave flagged and review later"
}
]
}]
For standalone CLI review, the script displays:
Transaction #12 (Confidence: 0.65)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Date: 2025-08-10
Merchant: GRAB HOLDINGS
Amount: -$35.50
Description: Point-of-Sale Transaction
Suggested: Dining & Restaurants
Actions:
[A] Accept - Keep as "Dining & Restaurants"
[C] Change - Specify a different category
[R] Rule - Accept and create rule for GRAB*
[S] Skip - Review later
Your choice: _
Action: Accept (A)
# Unflag transaction, keep existing category
db.execute("""
UPDATE transactions
SET flagged_for_review = 0, confidence_score = 1.0
WHERE id = ?
""", (txn_id,))
Action: Change (C)
# Display available categories
categories = db.get_category_names()
for i, cat in enumerate(categories, 1):
print(f" {i}. {cat}")
choice = input("Enter category number: ")
new_category = categories[int(choice) - 1]
# Update transaction
db.update_transaction_category(
transaction_id=txn_id,
category=new_category,
confidence_score=1.0,
flagged=False
)
Action: Rule (R)
# Accept categorization and offer rule creation
print(f"\nCreate rule: {merchant_pattern} → {category}")
print("\nRule conditions (optional):")
print(" [1] Any amount (simple pattern rule)")
print(" [2] Amount range (e.g., $20-50)")
print(" [3] Specific account type")
print(" [4] Add to memory instead (complex pattern)")
print(" [N] No rule, just accept")
choice = input("Choice: ")
if choice == "1":
# Simple pattern rule
rule = CategorizationRule(
id=None,
merchant_pattern=merchant_pattern,
category=category,
confidence=1.0,
user_confirmed=True,
auto_created=False,
notes=f"User-created during review on {datetime.now()}"
)
db.create_rule(rule)
elif choice == "2":
# Amount-based rule
min_amt = input("Minimum amount (or Enter to skip): ")
max_amt = input("Maximum amount (or Enter to skip): ")
rule = CategorizationRule(
id=None,
merchant_pattern=merchant_pattern,
category=category,
confidence=1.0,
rule_type="complex",
min_amount=float(min_amt) if min_amt else None,
max_amount=float(max_amt) if max_amt else None,
user_confirmed=True,
auto_created=False,
notes=f"User-created with amount filter during review"
)
db.create_rule(rule)
elif choice == "4":
# Add to memory file
update_memory_file(merchant_pattern, category, txn)
Action: Skip (S)
# Leave flagged, continue to next
continue
After review session, append learnings to data/TRANSACTION_MEMORY.md:
def update_memory_file(learnings: list[dict]):
memory_path = Path(config['data_directory']) / 'TRANSACTION_MEMORY.md'
# Create from template if doesn't exist
if not memory_path.exists():
template = Path('TRANSACTION_MEMORY.template.md')
if template.exists():
shutil.copy(template, memory_path)
# Append learnings
with open(memory_path, 'a') as f:
f.write(f"\n### Date: {datetime.now().strftime('%Y-%m-%d')} (Review Session)\n")
for learning in learnings:
if learning['action'] == 'confirmed':
f.write(f"- Confirmed: \"{learning['merchant']}\" → {learning['category']}\n")
elif learning['action'] == 'changed':
f.write(f"- Rejected: \"{learning['merchant']}\" suggested as {learning['from_category']}, changed to {learning['to_category']}\n")
elif learning['action'] == 'rule_created':
f.write(f"- Created rule: {learning['pattern']} → {learning['category']}")
if learning.get('conditions'):
f.write(f" (conditions: {learning['conditions']})")
f.write("\n")
f.write("\n")
print("\n" + "=" * 60)
print("Review Complete!")
print("=" * 60)
print(f"Reviewed: {reviewed_count}")
print(f"Accepted: {accepted_count}")
print(f"Changed: {changed_count}")
print(f"Rules created: {rules_created_count}")
print(f"Skipped: {skipped_count}")
print("=" * 60)
📋 Found 3 flagged transaction(s) to review
Transaction #1 of 3 (Confidence: 0.65)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Date: 2025-08-10
Merchant: AMAZON.COM
Amount: -$45.99
Description: Online Purchase
Suggested: Shopping
Actions:
[A] Accept - Keep as "Shopping"
[C] Change - Specify a different category
[R] Rule - Accept and create rule for AMAZON*
[S] Skip - Review later
Your choice: C
Available categories:
1. Groceries
2. Dining & Restaurants
...
14. Education
...
Enter category number: 14
✓ Updated to "Education"
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Transaction #2 of 3 (Confidence: 0.68)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Date: 2025-08-15
Merchant: GRAB HOLDINGS
Amount: -$8.50
Description: Point-of-Sale Transaction
Suggested: Transportation
Actions:
[A] Accept - Keep as "Transportation"
[C] Change - Specify a different category
[R] Rule - Accept and create rule for GRAB*
[S] Skip - Review later
Your choice: R
Create rule: GRAB* → Transportation
Rule conditions (optional):
[1] Any amount (simple pattern rule)
[2] Amount range (e.g., $20-50)
[3] Specific account type
[4] Add to memory instead (complex pattern)
[N] No rule, just accept
Choice: 2
Minimum amount (or Enter to skip):
Maximum amount (or Enter to skip): 15
✓ Created rule: GRAB* → Transportation (amount ≤ $15)
✓ Transaction accepted
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Transaction #3 of 3 (Confidence: 0.55)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Date: 2025-08-20
Merchant: VENDOR XYZ
Amount: -$120.00
Description: Payment
Suggested: Shopping
Actions:
[A] Accept - Keep as "Shopping"
[C] Change - Specify a different category
[R] Rule - Accept and create rule for VENDOR XYZ*
[S] Skip - Review later
Your choice: S
⏭ Skipped for later review
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
============================================================
Review Complete!
============================================================
Reviewed: 3
Accepted: 1
Changed: 1
Rules created: 1
Skipped: 1
============================================================
Memory updated: data/TRANSACTION_MEMORY.md
This skill is invoked by:
Invocation from ingestion:
uv run python scripts/review_flagged.py
user_confirmed=True and auto_created=Falseuser_confirmed=False and auto_created=True