Skip to content

Latest commit

 

History

History
152 lines (119 loc) · 4.52 KB

File metadata and controls

152 lines (119 loc) · 4.52 KB

Development Guide

Prerequisites

  • Python 3.11+
  • Git

Setup

git clone https://github.com/IFindMe/Facebook-cli.git
cd Facebook-cli
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

Run Tests

# All tests
pytest tests/ -v

# With coverage
pytest tests/ --cov=src/fb --cov-report=term-missing

# Specific test file
pytest tests/unit/test_errors.py -v

Type Check

mypy src/fb/ --ignore-missing-imports

Lint & Format

# Check
ruff check src/fb/
ruff format src/fb/ --check

# Auto-fix
ruff check src/fb/ --fix
ruff format src/fb/

Project Structure

src/fb/
├── cli.py              # Click entry point (33 commands)
├── api/
│   ├── client.py       # HTTP client (auth, retries, rate limits)
│   ├── pagination.py   # Cursor pagination
│   └── versioning.py   # API version management
├── auth/
│   ├── oauth.py        # OAuth authorization-code flow
│   ├── tokens.py       # Token storage and lifecycle
│   └── permissions.py  # Scope management
├── domains/
│   ├── pages.py        # Page operations
│   ├── posts.py        # Post operations
│   ├── comments.py     # Comment operations
│   ├── media.py        # Media uploads
│   ├── messenger.py    # Page messaging
│   └── insights.py     # Analytics
├── output/
│   ├── json.py         # JSON envelope output
│   ├── human.py        # Human-readable output
│   └── redact.py       # Token redaction
├── errors.py           # Error taxonomy (exit codes 2-12)
├── config.py           # XDG config loading
├── security.py         # Credential storage
├── capabilities.py     # Capability discovery
├── escape_hatch.py     # fb api command
├── validation.py       # Input validation
└── version.py          # Version constants

Architecture

The CLI follows a layered domain architecture (Option B):

High-level command → Domain service → Meta API client → Official Meta APIs
  • cli.py — Click groups/commands (thin, delegates only)
  • domains/ — Domain services (thin, ~100-200 lines each)
  • api/ — HTTP client with auth injection, retries, rate limiting
  • output/ — Formatting layer (JSON/human/redact)
  • errors.py — Centralized error taxonomy

Adding a New Domain

  1. Add src/fb/domains/new_feature.py — thin service: args → API path/params → client → structured data
  2. Add a Click group in cli.py delegating to it
  3. Add fixtures/tests in tests/mock_api/fixtures/ + tests/unit/

No existing files change structurally.

Key Invariants

  • Domains never import other domains
  • data and error are mutually exclusive in JSON envelope
  • Single version constant in version.py; no other file hardcodes a version
  • Tokens never in argv, logs, or plaintext config

Testing Strategy

Layer Tool Coverage
CLI parsing Click CliRunner flags, help, exit codes
Validation pytest bounds, conflicts, access_token rejection
API client respx version/base URL, auth injection, retries, rate-limit
Pagination pytest cursor follow, caps, pass-through
Error translation pytest Meta code → taxonomy matrix
Tokens pytest + fake keyring login, expiry, refresh, revoke, fallback
Security pytest redaction, argv-safety, perms, secure-delete

Hermetic Seams

  • respx — HTTP mock transport
  • CredentialStore — fake keyring for tests
  • Ephemeral-port socket for OAuth
  • FB_CONFIG_DIR env for filesystem isolation

Design Docs

  • docs/product/facebook-cli-overview.md — What/why/who
  • docs/product/capability-matrix.md — Full capability status matrix
  • docs/product/api-research.md — Meta API landscape (2026)
  • docs/architecture/architecture.md — Options comparison, Option B
  • docs/architecture/cli-design.md — Command tree, JSON contract, pagination
  • docs/architecture/authentication.md — OAuth flow, token storage
  • docs/architecture/security.md — Threat model, security boundaries
  • docs/architecture/testing-strategy.md — Test architecture
  • COMMANDS.md — Single source of truth for all commands

Git Workflow

  • Branch from main
  • Run tests, mypy, ruff before committing
  • Squash merge for clean history
  • Commit messages: imperative mood, concise
# Pre-commit checks
pytest tests/ -x -q && mypy src/fb/ --ignore-missing-imports && ruff check src/fb/