ipa
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m47s
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m47s
This commit is contained in:
parent
94f5d0c07d
commit
7a3a53f1a9
38
.agents/README.md
Normal file
38
.agents/README.md
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# .agents Directory
|
||||||
|
|
||||||
|
This directory contains agent configuration and skills for OpenAI Codex CLI.
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
.agents/
|
||||||
|
config.toml # Main configuration file
|
||||||
|
skills/ # Skill definitions
|
||||||
|
skill-name/
|
||||||
|
SKILL.md # Skill instructions
|
||||||
|
scripts/ # Optional scripts
|
||||||
|
docs/ # Optional documentation
|
||||||
|
README.md # This file
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The `config.toml` file controls:
|
||||||
|
- Model selection
|
||||||
|
- Approval policies
|
||||||
|
- Sandbox modes
|
||||||
|
- MCP server connections
|
||||||
|
- Skills configuration
|
||||||
|
|
||||||
|
## Skills
|
||||||
|
|
||||||
|
Skills are invoked using `$skill-name` syntax. Each skill has:
|
||||||
|
- YAML frontmatter with metadata
|
||||||
|
- Trigger and skip conditions
|
||||||
|
- Commands and examples
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
- Main instructions: `AGENTS.md` (project root)
|
||||||
|
- Local overrides: `.codex/AGENTS.override.md` (gitignored)
|
||||||
|
- Claude Flow: https://github.com/ruvnet/claude-flow
|
||||||
298
.agents/config.toml
Normal file
298
.agents/config.toml
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# Claude Flow V3 - Codex Configuration
|
||||||
|
# =============================================================================
|
||||||
|
# Generated by: @claude-flow/codex
|
||||||
|
# Documentation: https://github.com/ruvnet/claude-flow
|
||||||
|
#
|
||||||
|
# This file configures the Codex CLI for Claude Flow integration.
|
||||||
|
# Place in .agents/config.toml (project) or .codex/config.toml (user).
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Core Settings
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Model selection - the AI model to use for code generation
|
||||||
|
# Options: gpt-5.3-codex, gpt-4o, claude-sonnet, claude-opus
|
||||||
|
model = "gpt-5.3-codex"
|
||||||
|
|
||||||
|
# Approval policy determines when human approval is required
|
||||||
|
# - untrusted: Always require approval
|
||||||
|
# - on-failure: Require approval only after failures
|
||||||
|
# - on-request: Require approval for significant changes
|
||||||
|
# - never: Auto-approve all actions (use with caution)
|
||||||
|
approval_policy = "on-request"
|
||||||
|
|
||||||
|
# Sandbox mode controls file system access
|
||||||
|
# - read-only: Can only read files, no modifications
|
||||||
|
# - workspace-write: Can write within workspace directory
|
||||||
|
# - danger-full-access: Full file system access (dangerous)
|
||||||
|
sandbox_mode = "workspace-write"
|
||||||
|
|
||||||
|
# Web search enables internet access for research
|
||||||
|
# - disabled: No web access
|
||||||
|
# - cached: Use cached results when available
|
||||||
|
# - live: Always fetch fresh results
|
||||||
|
web_search = "cached"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Project Documentation
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Maximum bytes to read from AGENTS.md files
|
||||||
|
project_doc_max_bytes = 65536
|
||||||
|
|
||||||
|
# Fallback filenames if AGENTS.md not found
|
||||||
|
project_doc_fallback_filenames = [
|
||||||
|
"AGENTS.md",
|
||||||
|
"TEAM_GUIDE.md",
|
||||||
|
".agents.md"
|
||||||
|
]
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Features
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
[features]
|
||||||
|
# Enable child AGENTS.md guidance
|
||||||
|
child_agents_md = true
|
||||||
|
|
||||||
|
# Cache shell environment for faster repeated commands
|
||||||
|
shell_snapshot = true
|
||||||
|
|
||||||
|
# Smart approvals based on request context
|
||||||
|
request_rule = true
|
||||||
|
|
||||||
|
# Enable remote compaction for large histories
|
||||||
|
remote_compaction = true
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# MCP Servers
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
[mcp_servers.claude-flow]
|
||||||
|
command = "npx"
|
||||||
|
args = ["-y", "@claude-flow/cli@latest"]
|
||||||
|
enabled = true
|
||||||
|
tool_timeout_sec = 120
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Skills Configuration
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
[[skills.config]]
|
||||||
|
path = ".agents/skills/swarm-orchestration"
|
||||||
|
enabled = true
|
||||||
|
|
||||||
|
[[skills.config]]
|
||||||
|
path = ".agents/skills/memory-management"
|
||||||
|
enabled = true
|
||||||
|
|
||||||
|
[[skills.config]]
|
||||||
|
path = ".agents/skills/sparc-methodology"
|
||||||
|
enabled = true
|
||||||
|
|
||||||
|
[[skills.config]]
|
||||||
|
path = ".agents/skills/security-audit"
|
||||||
|
enabled = true
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Profiles
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Development profile - more permissive for local work
|
||||||
|
[profiles.dev]
|
||||||
|
approval_policy = "never"
|
||||||
|
sandbox_mode = "danger-full-access"
|
||||||
|
web_search = "live"
|
||||||
|
|
||||||
|
# Safe profile - maximum restrictions
|
||||||
|
[profiles.safe]
|
||||||
|
approval_policy = "untrusted"
|
||||||
|
sandbox_mode = "read-only"
|
||||||
|
web_search = "disabled"
|
||||||
|
|
||||||
|
# CI profile - for automated pipelines
|
||||||
|
[profiles.ci]
|
||||||
|
approval_policy = "never"
|
||||||
|
sandbox_mode = "workspace-write"
|
||||||
|
web_search = "cached"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# History
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
[history]
|
||||||
|
# Save all session transcripts
|
||||||
|
persistence = "save-all"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Shell Environment
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
[shell_environment_policy]
|
||||||
|
# Inherit environment variables
|
||||||
|
inherit = "core"
|
||||||
|
|
||||||
|
# Exclude sensitive variables
|
||||||
|
exclude = ["*_KEY", "*_SECRET", "*_TOKEN", "*_PASSWORD"]
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Sandbox Workspace Write Settings
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
[sandbox_workspace_write]
|
||||||
|
# Additional writable paths beyond workspace
|
||||||
|
writable_roots = []
|
||||||
|
|
||||||
|
# Allow network access
|
||||||
|
network_access = true
|
||||||
|
|
||||||
|
# Exclude temp directories
|
||||||
|
exclude_slash_tmp = false
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Security Settings
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
[security]
|
||||||
|
# Enable input validation for all user inputs
|
||||||
|
input_validation = true
|
||||||
|
|
||||||
|
# Prevent directory traversal attacks
|
||||||
|
path_traversal_prevention = true
|
||||||
|
|
||||||
|
# Scan for hardcoded secrets
|
||||||
|
secret_scanning = true
|
||||||
|
|
||||||
|
# Scan dependencies for known CVEs
|
||||||
|
cve_scanning = true
|
||||||
|
|
||||||
|
# Maximum file size for operations (bytes)
|
||||||
|
max_file_size = 10485760
|
||||||
|
|
||||||
|
# Allowed file extensions (empty = allow all)
|
||||||
|
allowed_extensions = []
|
||||||
|
|
||||||
|
# Blocked file patterns (regex)
|
||||||
|
blocked_patterns = ["\\.env$", "credentials\\.json$", "\\.pem$", "\\.key$"]
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Performance Settings
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
[performance]
|
||||||
|
# Maximum concurrent agents
|
||||||
|
max_agents = 8
|
||||||
|
|
||||||
|
# Task timeout in seconds
|
||||||
|
task_timeout = 300
|
||||||
|
|
||||||
|
# Memory limit per agent
|
||||||
|
memory_limit = "512MB"
|
||||||
|
|
||||||
|
# Enable response caching
|
||||||
|
cache_enabled = true
|
||||||
|
|
||||||
|
# Cache TTL in seconds
|
||||||
|
cache_ttl = 3600
|
||||||
|
|
||||||
|
# Enable parallel task execution
|
||||||
|
parallel_execution = true
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Logging Settings
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
[logging]
|
||||||
|
# Log level: debug, info, warn, error
|
||||||
|
level = "info"
|
||||||
|
|
||||||
|
# Log format: json, text, pretty
|
||||||
|
format = "pretty"
|
||||||
|
|
||||||
|
# Log destination: stdout, file, both
|
||||||
|
destination = "stdout"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Neural Intelligence Settings
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
[neural]
|
||||||
|
# Enable SONA (Self-Optimizing Neural Architecture)
|
||||||
|
sona_enabled = true
|
||||||
|
|
||||||
|
# Enable HNSW vector search
|
||||||
|
hnsw_enabled = true
|
||||||
|
|
||||||
|
# HNSW index parameters
|
||||||
|
hnsw_m = 16
|
||||||
|
hnsw_ef_construction = 200
|
||||||
|
hnsw_ef_search = 100
|
||||||
|
|
||||||
|
# Enable pattern learning
|
||||||
|
pattern_learning = true
|
||||||
|
|
||||||
|
# Learning rate for neural adaptation
|
||||||
|
learning_rate = 0.01
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Swarm Orchestration Settings
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
[swarm]
|
||||||
|
# Default topology: hierarchical, mesh, ring, star
|
||||||
|
default_topology = "hierarchical"
|
||||||
|
|
||||||
|
# Default strategy: balanced, specialized, adaptive
|
||||||
|
default_strategy = "specialized"
|
||||||
|
|
||||||
|
# Consensus algorithm: raft, byzantine, gossip
|
||||||
|
consensus = "raft"
|
||||||
|
|
||||||
|
# Enable anti-drift measures
|
||||||
|
anti_drift = true
|
||||||
|
|
||||||
|
# Checkpoint interval (tasks)
|
||||||
|
checkpoint_interval = 10
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Hooks Configuration
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
[hooks]
|
||||||
|
# Enable lifecycle hooks
|
||||||
|
enabled = true
|
||||||
|
|
||||||
|
# Pre-task hook
|
||||||
|
pre_task = true
|
||||||
|
|
||||||
|
# Post-task hook (for learning)
|
||||||
|
post_task = true
|
||||||
|
|
||||||
|
# Enable neural training on post-edit
|
||||||
|
train_on_edit = true
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Background Workers
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
[workers]
|
||||||
|
# Enable background workers
|
||||||
|
enabled = true
|
||||||
|
|
||||||
|
# Worker configuration
|
||||||
|
[workers.audit]
|
||||||
|
enabled = true
|
||||||
|
priority = "critical"
|
||||||
|
interval = 300
|
||||||
|
|
||||||
|
[workers.optimize]
|
||||||
|
enabled = true
|
||||||
|
priority = "high"
|
||||||
|
interval = 600
|
||||||
|
|
||||||
|
[workers.consolidate]
|
||||||
|
enabled = true
|
||||||
|
priority = "low"
|
||||||
|
interval = 1800
|
||||||
126
.agents/skills/memory-management/SKILL.md
Normal file
126
.agents/skills/memory-management/SKILL.md
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
---
|
||||||
|
name: memory-management
|
||||||
|
description: >
|
||||||
|
AgentDB memory system with HNSW vector search. Provides 150x-12,500x faster pattern retrieval, persistent storage, and semantic search capabilities for learning and knowledge management.
|
||||||
|
Use when: need to store successful patterns, searching for similar solutions, semantic lookup of past work, learning from previous tasks, sharing knowledge between agents, building knowledge base.
|
||||||
|
Skip when: no learning needed, ephemeral one-off tasks, external data sources available, read-only exploration.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Memory Management Skill
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
AgentDB memory system with HNSW vector search. Provides 150x-12,500x faster pattern retrieval, persistent storage, and semantic search capabilities for learning and knowledge management.
|
||||||
|
|
||||||
|
## When to Trigger
|
||||||
|
- need to store successful patterns
|
||||||
|
- searching for similar solutions
|
||||||
|
- semantic lookup of past work
|
||||||
|
- learning from previous tasks
|
||||||
|
- sharing knowledge between agents
|
||||||
|
- building knowledge base
|
||||||
|
|
||||||
|
## When to Skip
|
||||||
|
- no learning needed
|
||||||
|
- ephemeral one-off tasks
|
||||||
|
- external data sources available
|
||||||
|
- read-only exploration
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
### Store Pattern
|
||||||
|
Store a pattern or knowledge item in memory
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli memory store --key "[key]" --value "[value]" --namespace patterns
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli memory store --key "auth-jwt-pattern" --value "JWT validation with refresh tokens" --namespace patterns
|
||||||
|
```
|
||||||
|
|
||||||
|
### Semantic Search
|
||||||
|
Search memory using semantic similarity
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli memory search --query "[search terms]" --limit 10
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli memory search --query "authentication best practices" --limit 5
|
||||||
|
```
|
||||||
|
|
||||||
|
### Retrieve Entry
|
||||||
|
Retrieve a specific memory entry by key
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli memory get --key "[key]" --namespace [namespace]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli memory get --key "auth-jwt-pattern" --namespace patterns
|
||||||
|
```
|
||||||
|
|
||||||
|
### List Entries
|
||||||
|
List all entries in a namespace
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli memory list --namespace [namespace]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli memory list --namespace patterns --limit 20
|
||||||
|
```
|
||||||
|
|
||||||
|
### Delete Entry
|
||||||
|
Delete a memory entry
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli memory delete --key "[key]" --namespace [namespace]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Initialize HNSW Index
|
||||||
|
Initialize HNSW vector search index
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli memory init --enable-hnsw
|
||||||
|
```
|
||||||
|
|
||||||
|
### Memory Stats
|
||||||
|
Show memory usage statistics
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli memory stats
|
||||||
|
```
|
||||||
|
|
||||||
|
### Export Memory
|
||||||
|
Export memory to JSON
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli memory export --output memory-backup.json
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Scripts
|
||||||
|
|
||||||
|
| Script | Path | Description |
|
||||||
|
|--------|------|-------------|
|
||||||
|
| `memory-backup` | `.agents/scripts/memory-backup.sh` | Backup memory to external storage |
|
||||||
|
| `memory-consolidate` | `.agents/scripts/memory-consolidate.sh` | Consolidate and optimize memory |
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
| Document | Path | Description |
|
||||||
|
|----------|------|-------------|
|
||||||
|
| `HNSW Guide` | `docs/hnsw.md` | HNSW vector search configuration |
|
||||||
|
| `Memory Schema` | `docs/memory-schema.md` | Memory namespace and schema reference |
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
1. Check memory for existing patterns before starting
|
||||||
|
2. Use hierarchical topology for coordination
|
||||||
|
3. Store successful patterns after completion
|
||||||
|
4. Document any new learnings
|
||||||
135
.agents/skills/security-audit/SKILL.md
Normal file
135
.agents/skills/security-audit/SKILL.md
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
---
|
||||||
|
name: security-audit
|
||||||
|
description: >
|
||||||
|
Comprehensive security scanning and vulnerability detection. Includes input validation, path traversal prevention, CVE detection, and secure coding pattern enforcement.
|
||||||
|
Use when: authentication implementation, authorization logic, payment processing, user data handling, API endpoint creation, file upload handling, database queries, external API integration.
|
||||||
|
Skip when: read-only operations on public data, internal development tooling, static documentation, styling changes.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Security Audit Skill
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
Comprehensive security scanning and vulnerability detection. Includes input validation, path traversal prevention, CVE detection, and secure coding pattern enforcement.
|
||||||
|
|
||||||
|
## When to Trigger
|
||||||
|
- authentication implementation
|
||||||
|
- authorization logic
|
||||||
|
- payment processing
|
||||||
|
- user data handling
|
||||||
|
- API endpoint creation
|
||||||
|
- file upload handling
|
||||||
|
- database queries
|
||||||
|
- external API integration
|
||||||
|
|
||||||
|
## When to Skip
|
||||||
|
- read-only operations on public data
|
||||||
|
- internal development tooling
|
||||||
|
- static documentation
|
||||||
|
- styling changes
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
### Full Security Scan
|
||||||
|
Run comprehensive security analysis on the codebase
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli security scan --depth full
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli security scan --depth full --output security-report.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Input Validation Check
|
||||||
|
Check for input validation issues
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli security scan --check input-validation
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli security scan --check input-validation --path ./src/api
|
||||||
|
```
|
||||||
|
|
||||||
|
### Path Traversal Check
|
||||||
|
Check for path traversal vulnerabilities
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli security scan --check path-traversal
|
||||||
|
```
|
||||||
|
|
||||||
|
### SQL Injection Check
|
||||||
|
Check for SQL injection vulnerabilities
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli security scan --check sql-injection
|
||||||
|
```
|
||||||
|
|
||||||
|
### XSS Check
|
||||||
|
Check for cross-site scripting vulnerabilities
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli security scan --check xss
|
||||||
|
```
|
||||||
|
|
||||||
|
### CVE Scan
|
||||||
|
Scan dependencies for known CVEs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli security cve --scan
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli security cve --scan --severity high
|
||||||
|
```
|
||||||
|
|
||||||
|
### Security Audit Report
|
||||||
|
Generate full security audit report
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli security audit --report
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli security audit --report --format markdown --output SECURITY.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Threat Modeling
|
||||||
|
Run threat modeling analysis
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli security threats --analyze
|
||||||
|
```
|
||||||
|
|
||||||
|
### Validate Secrets
|
||||||
|
Check for hardcoded secrets
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli security validate --check secrets
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Scripts
|
||||||
|
|
||||||
|
| Script | Path | Description |
|
||||||
|
|--------|------|-------------|
|
||||||
|
| `security-scan` | `.agents/scripts/security-scan.sh` | Run full security scan pipeline |
|
||||||
|
| `cve-remediate` | `.agents/scripts/cve-remediate.sh` | Auto-remediate known CVEs |
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
| Document | Path | Description |
|
||||||
|
|----------|------|-------------|
|
||||||
|
| `Security Checklist` | `docs/security-checklist.md` | Security review checklist |
|
||||||
|
| `OWASP Guide` | `docs/owasp-top10.md` | OWASP Top 10 mitigation guide |
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
1. Check memory for existing patterns before starting
|
||||||
|
2. Use hierarchical topology for coordination
|
||||||
|
3. Store successful patterns after completion
|
||||||
|
4. Document any new learnings
|
||||||
118
.agents/skills/sparc-methodology/SKILL.md
Normal file
118
.agents/skills/sparc-methodology/SKILL.md
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
---
|
||||||
|
name: sparc-methodology
|
||||||
|
description: >
|
||||||
|
SPARC development workflow: Specification, Pseudocode, Architecture, Refinement, Completion. A structured approach for complex implementations that ensures thorough planning before coding.
|
||||||
|
Use when: new feature implementation, complex implementations, architectural changes, system redesign, integration work, unclear requirements.
|
||||||
|
Skip when: simple bug fixes, documentation updates, configuration changes, well-defined small tasks, routine maintenance.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Sparc Methodology Skill
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
SPARC development workflow: Specification, Pseudocode, Architecture, Refinement, Completion. A structured approach for complex implementations that ensures thorough planning before coding.
|
||||||
|
|
||||||
|
## When to Trigger
|
||||||
|
- new feature implementation
|
||||||
|
- complex implementations
|
||||||
|
- architectural changes
|
||||||
|
- system redesign
|
||||||
|
- integration work
|
||||||
|
- unclear requirements
|
||||||
|
|
||||||
|
## When to Skip
|
||||||
|
- simple bug fixes
|
||||||
|
- documentation updates
|
||||||
|
- configuration changes
|
||||||
|
- well-defined small tasks
|
||||||
|
- routine maintenance
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
### Specification Phase
|
||||||
|
Define requirements, acceptance criteria, and constraints
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli hooks route --task "specification: [requirements]"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli hooks route --task "specification: user authentication with OAuth2, MFA, and session management"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pseudocode Phase
|
||||||
|
Write high-level pseudocode for the implementation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli hooks route --task "pseudocode: [feature]"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli hooks route --task "pseudocode: OAuth2 login flow with token refresh"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Architecture Phase
|
||||||
|
Design system structure, interfaces, and dependencies
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli hooks route --task "architecture: [design]"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli hooks route --task "architecture: auth module with service layer, repository, and API endpoints"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Refinement Phase
|
||||||
|
Iterate on the design based on feedback
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli hooks route --task "refinement: [feedback]"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli hooks route --task "refinement: add rate limiting and brute force protection"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Completion Phase
|
||||||
|
Finalize implementation with tests and documentation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli hooks route --task "completion: [final checks]"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli hooks route --task "completion: verify all tests pass, update API docs, security review"
|
||||||
|
```
|
||||||
|
|
||||||
|
### SPARC Coordinator
|
||||||
|
Spawn SPARC coordinator agent
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli agent spawn --type sparc-coord --name sparc-lead
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Scripts
|
||||||
|
|
||||||
|
| Script | Path | Description |
|
||||||
|
|--------|------|-------------|
|
||||||
|
| `sparc-init` | `.agents/scripts/sparc-init.sh` | Initialize SPARC workflow for a new feature |
|
||||||
|
| `sparc-review` | `.agents/scripts/sparc-review.sh` | Run SPARC phase review checklist |
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
| Document | Path | Description |
|
||||||
|
|----------|------|-------------|
|
||||||
|
| `SPARC Overview` | `docs/sparc.md` | Complete SPARC methodology guide |
|
||||||
|
| `Phase Templates` | `docs/sparc-templates.md` | Templates for each SPARC phase |
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
1. Check memory for existing patterns before starting
|
||||||
|
2. Use hierarchical topology for coordination
|
||||||
|
3. Store successful patterns after completion
|
||||||
|
4. Document any new learnings
|
||||||
114
.agents/skills/swarm-orchestration/SKILL.md
Normal file
114
.agents/skills/swarm-orchestration/SKILL.md
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
---
|
||||||
|
name: swarm-orchestration
|
||||||
|
description: >
|
||||||
|
Multi-agent swarm coordination for complex tasks. Uses hierarchical topology with specialized agents to break down and execute complex work across multiple files and modules.
|
||||||
|
Use when: 3+ files need changes, new feature implementation, cross-module refactoring, API changes with tests, security-related changes, performance optimization across codebase, database schema changes.
|
||||||
|
Skip when: single file edits, simple bug fixes (1-2 lines), documentation updates, configuration changes, quick exploration.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Swarm Orchestration Skill
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
Multi-agent swarm coordination for complex tasks. Uses hierarchical topology with specialized agents to break down and execute complex work across multiple files and modules.
|
||||||
|
|
||||||
|
## When to Trigger
|
||||||
|
- 3+ files need changes
|
||||||
|
- new feature implementation
|
||||||
|
- cross-module refactoring
|
||||||
|
- API changes with tests
|
||||||
|
- security-related changes
|
||||||
|
- performance optimization across codebase
|
||||||
|
- database schema changes
|
||||||
|
|
||||||
|
## When to Skip
|
||||||
|
- single file edits
|
||||||
|
- simple bug fixes (1-2 lines)
|
||||||
|
- documentation updates
|
||||||
|
- configuration changes
|
||||||
|
- quick exploration
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
### Initialize Swarm
|
||||||
|
Start a new swarm with hierarchical topology (anti-drift)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli swarm init --topology hierarchical --max-agents 8 --strategy specialized
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli swarm init --topology hierarchical --max-agents 6 --strategy specialized
|
||||||
|
```
|
||||||
|
|
||||||
|
### Route Task
|
||||||
|
Route a task to the appropriate agents based on task type
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli hooks route --task "[task description]"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli hooks route --task "implement OAuth2 authentication flow"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Spawn Agent
|
||||||
|
Spawn a specific agent type
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli agent spawn --type [type] --name [name]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli agent spawn --type coder --name impl-auth
|
||||||
|
```
|
||||||
|
|
||||||
|
### Monitor Status
|
||||||
|
Check the current swarm status
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli swarm status --verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
### Orchestrate Task
|
||||||
|
Orchestrate a task across multiple agents
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli task orchestrate --task "[task]" --strategy adaptive
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli task orchestrate --task "refactor auth module" --strategy parallel --max-agents 4
|
||||||
|
```
|
||||||
|
|
||||||
|
### List Agents
|
||||||
|
List all active agents
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli agent list --filter active
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Scripts
|
||||||
|
|
||||||
|
| Script | Path | Description |
|
||||||
|
|--------|------|-------------|
|
||||||
|
| `swarm-start` | `.agents/scripts/swarm-start.sh` | Initialize swarm with default settings |
|
||||||
|
| `swarm-monitor` | `.agents/scripts/swarm-monitor.sh` | Real-time swarm monitoring dashboard |
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
| Document | Path | Description |
|
||||||
|
|----------|------|-------------|
|
||||||
|
| `Agent Types` | `docs/agents.md` | Complete list of agent types and capabilities |
|
||||||
|
| `Topology Guide` | `docs/topology.md` | Swarm topology configuration guide |
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
1. Check memory for existing patterns before starting
|
||||||
|
2. Use hierarchical topology for coordination
|
||||||
|
3. Store successful patterns after completion
|
||||||
|
4. Document any new learnings
|
||||||
12
.gitignore
vendored
12
.gitignore
vendored
@ -67,3 +67,15 @@ script/*.sh
|
|||||||
|
|
||||||
# ==================== 临时笔记 ====================
|
# ==================== 临时笔记 ====================
|
||||||
订单日志.txt
|
订单日志.txt
|
||||||
|
|
||||||
|
# Codex local configuration
|
||||||
|
.codex/
|
||||||
|
|
||||||
|
# Claude Flow runtime data
|
||||||
|
.claude-flow/data/
|
||||||
|
.claude-flow/logs/
|
||||||
|
|
||||||
|
# Environment variables
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|||||||
145
AGENTS.md
Normal file
145
AGENTS.md
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
# ppanel-server
|
||||||
|
|
||||||
|
> Multi-agent orchestration framework for agentic coding
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
A Claude Flow powered project
|
||||||
|
|
||||||
|
**Tech Stack**: TypeScript, Node.js
|
||||||
|
**Architecture**: Domain-Driven Design with bounded contexts
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test
|
||||||
|
```bash
|
||||||
|
npm test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Development
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## Agent Coordination
|
||||||
|
|
||||||
|
### Swarm Configuration
|
||||||
|
|
||||||
|
This project uses hierarchical swarm coordination for complex tasks:
|
||||||
|
|
||||||
|
| Setting | Value | Purpose |
|
||||||
|
|---------|-------|---------|
|
||||||
|
| Topology | `hierarchical` | Queen-led coordination (anti-drift) |
|
||||||
|
| Max Agents | 8 | Optimal team size |
|
||||||
|
| Strategy | `specialized` | Clear role boundaries |
|
||||||
|
| Consensus | `raft` | Leader-based consistency |
|
||||||
|
|
||||||
|
### When to Use Swarms
|
||||||
|
|
||||||
|
**Invoke swarm for:**
|
||||||
|
- Multi-file changes (3+ files)
|
||||||
|
- New feature implementation
|
||||||
|
- Cross-module refactoring
|
||||||
|
- API changes with tests
|
||||||
|
- Security-related changes
|
||||||
|
- Performance optimization
|
||||||
|
|
||||||
|
**Skip swarm for:**
|
||||||
|
- Single file edits
|
||||||
|
- Simple bug fixes (1-2 lines)
|
||||||
|
- Documentation updates
|
||||||
|
- Configuration changes
|
||||||
|
|
||||||
|
### Available Skills
|
||||||
|
|
||||||
|
Use `$skill-name` syntax to invoke:
|
||||||
|
|
||||||
|
| Skill | Use Case |
|
||||||
|
|-------|----------|
|
||||||
|
| `$swarm-orchestration` | Multi-agent task coordination |
|
||||||
|
| `$memory-management` | Pattern storage and retrieval |
|
||||||
|
| `$sparc-methodology` | Structured development workflow |
|
||||||
|
| `$security-audit` | Security scanning and CVE detection |
|
||||||
|
|
||||||
|
### Agent Types
|
||||||
|
|
||||||
|
| Type | Role | Use Case |
|
||||||
|
|------|------|----------|
|
||||||
|
| `researcher` | Requirements analysis | Understanding scope |
|
||||||
|
| `architect` | System design | Planning structure |
|
||||||
|
| `coder` | Implementation | Writing code |
|
||||||
|
| `tester` | Test creation | Quality assurance |
|
||||||
|
| `reviewer` | Code review | Security and quality |
|
||||||
|
|
||||||
|
## Code Standards
|
||||||
|
|
||||||
|
### File Organization
|
||||||
|
- **NEVER** save to root folder
|
||||||
|
- `/src` - Source code files
|
||||||
|
- `/tests` - Test files
|
||||||
|
- `/docs` - Documentation
|
||||||
|
- `/config` - Configuration files
|
||||||
|
|
||||||
|
### Quality Rules
|
||||||
|
- Files under 500 lines
|
||||||
|
- No hardcoded secrets
|
||||||
|
- Input validation at boundaries
|
||||||
|
- Typed interfaces for public APIs
|
||||||
|
- TDD London School (mock-first) preferred
|
||||||
|
|
||||||
|
### Commit Messages
|
||||||
|
```
|
||||||
|
<type>(<scope>): <description>
|
||||||
|
|
||||||
|
[optional body]
|
||||||
|
|
||||||
|
Co-Authored-By: claude-flow <ruv@ruv.net>
|
||||||
|
```
|
||||||
|
|
||||||
|
Types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `chore`
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
### Critical Rules
|
||||||
|
- NEVER commit secrets, credentials, or .env files
|
||||||
|
- NEVER hardcode API keys
|
||||||
|
- Always validate user input
|
||||||
|
- Use parameterized queries for SQL
|
||||||
|
- Sanitize output to prevent XSS
|
||||||
|
|
||||||
|
### Path Security
|
||||||
|
- Validate all file paths
|
||||||
|
- Prevent directory traversal (../)
|
||||||
|
- Use absolute paths internally
|
||||||
|
|
||||||
|
## Memory System
|
||||||
|
|
||||||
|
### Storing Patterns
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli memory store \
|
||||||
|
--key "pattern-name" \
|
||||||
|
--value "pattern description" \
|
||||||
|
--namespace patterns
|
||||||
|
```
|
||||||
|
|
||||||
|
### Searching Memory
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli memory search \
|
||||||
|
--query "search terms" \
|
||||||
|
--namespace patterns
|
||||||
|
```
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
- Documentation: https://github.com/ruvnet/claude-flow
|
||||||
|
- Issues: https://github.com/ruvnet/claude-flow/issues
|
||||||
@ -61,6 +61,11 @@ type customOrderLogicModel interface {
|
|||||||
IsUserEligibleForNewOrder(ctx context.Context, userID int64) (bool, error)
|
IsUserEligibleForNewOrder(ctx context.Context, userID int64) (bool, error)
|
||||||
QueryDailyOrdersList(ctx context.Context, date time.Time) ([]OrdersTotalWithDate, error)
|
QueryDailyOrdersList(ctx context.Context, date time.Time) ([]OrdersTotalWithDate, error)
|
||||||
QueryMonthlyOrdersList(ctx context.Context, date time.Time) ([]OrdersTotalWithDate, error)
|
QueryMonthlyOrdersList(ctx context.Context, date time.Time) ([]OrdersTotalWithDate, error)
|
||||||
|
// FindPendingIAPOrders 查询待对账的 Apple IAP 订单
|
||||||
|
// minAge: 订单创建时间距今最短时长(避免扫到刚创建的)
|
||||||
|
// maxAge: 订单创建时间距今最长时长(超出此范围由日终对账处理)
|
||||||
|
// requireTradeNo: true=只查 trade_no 非空的(第二层),false=全部(第三层)
|
||||||
|
FindPendingIAPOrders(ctx context.Context, minAge, maxAge time.Duration, requireTradeNo bool) ([]*Order, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserCounts User counts for new and renewal users
|
// UserCounts User counts for new and renewal users
|
||||||
@ -281,6 +286,24 @@ func (m *customOrderModel) QueryDailyOrdersList(ctx context.Context, date time.T
|
|||||||
return results, err
|
return results, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindPendingIAPOrders 查询待对账的 Apple IAP 待支付订单
|
||||||
|
func (m *customOrderModel) FindPendingIAPOrders(ctx context.Context, minAge, maxAge time.Duration, requireTradeNo bool) ([]*Order, error) {
|
||||||
|
var list []*Order
|
||||||
|
now := time.Now()
|
||||||
|
err := m.QueryNoCacheCtx(ctx, &list, func(conn *gorm.DB, v interface{}) error {
|
||||||
|
q := conn.Model(&Order{}).
|
||||||
|
Where("method = ? AND status = ? AND created_at < ? AND created_at > ?",
|
||||||
|
"apple_iap", 1, now.Add(-minAge), now.Add(-maxAge)).
|
||||||
|
Order("created_at ASC").
|
||||||
|
Limit(100)
|
||||||
|
if requireTradeNo {
|
||||||
|
q = q.Where("trade_no != '' AND trade_no IS NOT NULL")
|
||||||
|
}
|
||||||
|
return q.Find(&list).Error
|
||||||
|
})
|
||||||
|
return list, err
|
||||||
|
}
|
||||||
|
|
||||||
// QueryMonthlyOrdersList 查询过去 6 个月订单统计(包含当前月)
|
// QueryMonthlyOrdersList 查询过去 6 个月订单统计(包含当前月)
|
||||||
func (m *customOrderModel) QueryMonthlyOrdersList(ctx context.Context, date time.Time) ([]OrdersTotalWithDate, error) {
|
func (m *customOrderModel) QueryMonthlyOrdersList(ctx context.Context, date time.Time) ([]OrdersTotalWithDate, error) {
|
||||||
var results []OrdersTotalWithDate
|
var results []OrdersTotalWithDate
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package handler
|
|||||||
import (
|
import (
|
||||||
"github.com/hibiken/asynq"
|
"github.com/hibiken/asynq"
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
|
iapLogic "github.com/perfect-panel/server/queue/logic/iap"
|
||||||
orderLogic "github.com/perfect-panel/server/queue/logic/order"
|
orderLogic "github.com/perfect-panel/server/queue/logic/order"
|
||||||
smslogic "github.com/perfect-panel/server/queue/logic/sms"
|
smslogic "github.com/perfect-panel/server/queue/logic/sms"
|
||||||
"github.com/perfect-panel/server/queue/logic/subscription"
|
"github.com/perfect-panel/server/queue/logic/subscription"
|
||||||
@ -43,4 +44,8 @@ func RegisterHandlers(mux *asynq.ServeMux, serverCtx *svc.ServiceContext) {
|
|||||||
|
|
||||||
// ForthwithQuotaTask
|
// ForthwithQuotaTask
|
||||||
mux.Handle(types.ForthwithQuotaTask, task.NewQuotaTaskLogic(serverCtx))
|
mux.Handle(types.ForthwithQuotaTask, task.NewQuotaTaskLogic(serverCtx))
|
||||||
|
|
||||||
|
// Apple IAP 对账(第二层:5min 扫描 + 第三层:日终全量)
|
||||||
|
mux.Handle(types.SchedulerIAPReconcile, iapLogic.NewReconcileLogic(serverCtx))
|
||||||
|
mux.Handle(types.SchedulerIAPDailyReconcile, iapLogic.NewDailyReconcileLogic(serverCtx))
|
||||||
}
|
}
|
||||||
|
|||||||
27
queue/logic/iap/dailyReconcileLogic.go
Normal file
27
queue/logic/iap/dailyReconcileLogic.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package iap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/hibiken/asynq"
|
||||||
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
|
"github.com/perfect-panel/server/pkg/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DailyReconcileLogic 第三层:日终全量对账(每天 02:00)
|
||||||
|
// 扫描过去 48h 内所有未支付的 IAP 订单(含 trade_no 为空的极端情况)
|
||||||
|
type DailyReconcileLogic struct {
|
||||||
|
inner *ReconcileLogic
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDailyReconcileLogic(svc *svc.ServiceContext) *DailyReconcileLogic {
|
||||||
|
return &DailyReconcileLogic{inner: &ReconcileLogic{svc: svc}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *DailyReconcileLogic) ProcessTask(ctx context.Context, _ *asynq.Task) error {
|
||||||
|
logger.Infof("[IAPDailyReconcile] start at %s", time.Now().Format("2006-01-02 15:04:05"))
|
||||||
|
// 第三层:扫描 1min ~ 48h,trade_no 非空(trade_no 为空说明客户端从未上传过 token,服务端无法主动补单)
|
||||||
|
// 实际上与第二层的区别是时间窗口:覆盖全天的遗漏
|
||||||
|
return l.inner.reconcile(ctx, 1*time.Minute, 48*time.Hour, true)
|
||||||
|
}
|
||||||
134
queue/logic/iap/reconcileLogic.go
Normal file
134
queue/logic/iap/reconcileLogic.go
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
package iap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/hibiken/asynq"
|
||||||
|
"github.com/perfect-panel/server/internal/model/payment"
|
||||||
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
|
iapapple "github.com/perfect-panel/server/pkg/iap/apple"
|
||||||
|
"github.com/perfect-panel/server/pkg/logger"
|
||||||
|
pkgpayment "github.com/perfect-panel/server/pkg/payment"
|
||||||
|
queueTypes "github.com/perfect-panel/server/queue/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ReconcileLogic 第二层:每 5 分钟扫描 trade_no 非空的待支付 IAP 订单
|
||||||
|
type ReconcileLogic struct {
|
||||||
|
svc *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewReconcileLogic(svc *svc.ServiceContext) *ReconcileLogic {
|
||||||
|
return &ReconcileLogic{svc: svc}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *ReconcileLogic) ProcessTask(ctx context.Context, _ *asynq.Task) error {
|
||||||
|
logger.Infof("[IAPReconcile] start at %s", time.Now().Format("2006-01-02 15:04:05"))
|
||||||
|
return l.reconcile(ctx, 5*time.Minute, 48*time.Hour, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// reconcile 核心对账逻辑,被第二层和第三层共享
|
||||||
|
func (l *ReconcileLogic) reconcile(ctx context.Context, minAge, maxAge time.Duration, requireTradeNo bool) error {
|
||||||
|
apiCfg, err := l.loadAppleAPIConfig(ctx)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("[IAPReconcile] load apple config error: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if apiCfg == nil {
|
||||||
|
logger.Infof("[IAPReconcile] no enabled apple iap payment found, skip")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
orders, err := l.svc.OrderModel.FindPendingIAPOrders(ctx, minAge, maxAge, requireTradeNo)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("[IAPReconcile] find pending orders error: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if len(orders) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
logger.Infof("[IAPReconcile] found %d pending IAP orders (requireTradeNo=%v)", len(orders), requireTradeNo)
|
||||||
|
|
||||||
|
for _, ord := range orders {
|
||||||
|
if ord.TradeNo == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// 用 originalTransactionId(即 trade_no)向 Apple Server API 查询交易详情
|
||||||
|
jws, e := iapapple.GetTransactionInfo(*apiCfg, ord.TradeNo)
|
||||||
|
if e != nil {
|
||||||
|
logger.Errorf("[IAPReconcile] GetTransactionInfo error: orderNo=%s tradeNo=%s err=%v",
|
||||||
|
ord.OrderNo, ord.TradeNo, e)
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// 解析 JWS(不校验证书链,只读取 payload)
|
||||||
|
txPayload, e := iapapple.ParseTransactionJWS(jws)
|
||||||
|
if e != nil {
|
||||||
|
logger.Errorf("[IAPReconcile] ParseTransactionJWS error: orderNo=%s err=%v", ord.OrderNo, e)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if txPayload.RevocationDate != nil {
|
||||||
|
// 苹果已撤销交易 → 关闭订单
|
||||||
|
logger.Infof("[IAPReconcile] transaction revoked, closing order: %s", ord.OrderNo)
|
||||||
|
_ = l.svc.OrderModel.UpdateOrderStatus(ctx, ord.OrderNo, 3)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// 正常已付款交易 → enqueue 激活(activateOrderLogic 内部有幂等保护)
|
||||||
|
payload, _ := json.Marshal(queueTypes.ForthwithActivateOrderPayload{OrderNo: ord.OrderNo})
|
||||||
|
task := asynq.NewTask(queueTypes.ForthwithActivateOrder, payload)
|
||||||
|
if _, e = l.svc.Queue.EnqueueContext(ctx, task); e != nil {
|
||||||
|
logger.Errorf("[IAPReconcile] enqueue activate error: orderNo=%s err=%v", ord.OrderNo, e)
|
||||||
|
} else {
|
||||||
|
logger.Infof("[IAPReconcile] enqueued activate: %s", ord.OrderNo)
|
||||||
|
}
|
||||||
|
time.Sleep(100 * time.Millisecond) // 避免 Apple API 限频
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadAppleAPIConfig 从 payment 表读取第一个启用的 Apple IAP 支付方式配置
|
||||||
|
func (l *ReconcileLogic) loadAppleAPIConfig(ctx context.Context) (*iapapple.ServerAPIConfig, error) {
|
||||||
|
pays, err := l.svc.PaymentModel.FindListByPlatform(ctx, pkgpayment.AppleIAP.String())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, pay := range pays {
|
||||||
|
if pay.Enable == nil || !*pay.Enable || pay.Config == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var cfg payment.AppleIAPConfig
|
||||||
|
if e := cfg.Unmarshal([]byte(pay.Config)); e != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if cfg.KeyID == "" || cfg.IssuerID == "" || cfg.PrivateKey == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
apiCfg := &iapapple.ServerAPIConfig{
|
||||||
|
KeyID: cfg.KeyID,
|
||||||
|
IssuerID: cfg.IssuerID,
|
||||||
|
PrivateKey: fixPEM(cfg.PrivateKey),
|
||||||
|
Sandbox: cfg.Sandbox,
|
||||||
|
}
|
||||||
|
// 从 site custom data 读取 BundleID
|
||||||
|
var customData struct {
|
||||||
|
IapBundleId string `json:"iapBundleId"`
|
||||||
|
}
|
||||||
|
if l.svc.Config.Site.CustomData != "" {
|
||||||
|
_ = json.Unmarshal([]byte(l.svc.Config.Site.CustomData), &customData)
|
||||||
|
apiCfg.BundleID = customData.IapBundleId
|
||||||
|
}
|
||||||
|
return apiCfg, nil
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fixPEM(key string) string {
|
||||||
|
if !strings.Contains(key, "\n") && strings.Contains(key, "BEGIN PRIVATE KEY") {
|
||||||
|
key = strings.ReplaceAll(key, " ", "\n")
|
||||||
|
key = strings.ReplaceAll(key, "-----BEGIN\nPRIVATE\nKEY-----", "-----BEGIN PRIVATE KEY-----")
|
||||||
|
key = strings.ReplaceAll(key, "-----END\nPRIVATE\nKEY-----", "-----END PRIVATE KEY-----")
|
||||||
|
}
|
||||||
|
return key
|
||||||
|
}
|
||||||
@ -5,4 +5,6 @@ const (
|
|||||||
SchedulerTotalServerData = "scheduler:total:server"
|
SchedulerTotalServerData = "scheduler:total:server"
|
||||||
SchedulerResetTraffic = "scheduler:reset:traffic"
|
SchedulerResetTraffic = "scheduler:reset:traffic"
|
||||||
SchedulerTrafficStat = "scheduler:traffic:stat"
|
SchedulerTrafficStat = "scheduler:traffic:stat"
|
||||||
|
SchedulerIAPReconcile = "scheduler:iap:reconcile" // 第二层:每 5 分钟扫描待支付 IAP 订单
|
||||||
|
SchedulerIAPDailyReconcile = "scheduler:iap:daily:reconcile" // 第三层:日终全量对账
|
||||||
)
|
)
|
||||||
|
|||||||
@ -52,6 +52,18 @@ func (m *Service) Start() {
|
|||||||
logger.Errorf("register update exchange rate task failed: %s", err.Error())
|
logger.Errorf("register update exchange rate task failed: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// schedule Apple IAP reconcile: every 5 minutes (第二层补单)
|
||||||
|
iapReconcileTask := asynq.NewTask(types.SchedulerIAPReconcile, nil)
|
||||||
|
if _, err := m.server.Register("@every 5m", iapReconcileTask, asynq.MaxRetry(1)); err != nil {
|
||||||
|
logger.Errorf("register iap reconcile task failed: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// schedule Apple IAP daily reconcile: every day at 02:00 (第三层日终对账)
|
||||||
|
iapDailyTask := asynq.NewTask(types.SchedulerIAPDailyReconcile, nil)
|
||||||
|
if _, err := m.server.Register("0 2 * * *", iapDailyTask, asynq.MaxRetry(1)); err != nil {
|
||||||
|
logger.Errorf("register iap daily reconcile task failed: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
if err := m.server.Run(); err != nil {
|
if err := m.server.Run(); err != nil {
|
||||||
logger.Errorf("run scheduler failed: %s", err.Error())
|
logger.Errorf("run scheduler failed: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user