Files
studipsync/AGENTS.md

6.4 KiB
Raw Permalink Blame History

StudIP Sync Agent

This document equips future agents with the current mental model for the studip-sync CLI so new work can focus on real gaps instead of rediscovering context.

Mission & Constraints

  • Goal: one-way sync of documents from Stud.IPs JSON:API (Uni Trier) to the local filesystem using Rust (async tokio, reqwest, serde, TOML config/state).
  • Target platform: Linux (Arch) following the XDG base directory spec.
  • Binary name must stay studip-sync; code must stay cargo fmt + cargo clippy --all-targets --all-features -- -D warnings + cargo test clean.
  • All configuration/state is TOML. The config file (mode 0600) stores the Base64-encoded Basic auth string; state caches user/semester/course/file metadata.
  • Directory layout requirement: <download_root>/<semester_key>/<course>/<studip-folder-hierarchy>/<files>. Never upload to Stud.IP; pruning is opt-in via --prune.

Rust edition note: The crate currently targets Rust 2024 even though the original brief called for 2021. Keep this divergence in mind if MSRV compatibility matters.

Repository Map

Path Purpose
src/main.rs Minimal entry point that parses CLI args and drives async runtime.
src/cli.rs All subcommand implementations plus sync logic, prompt helpers, pruning, naming utilities, and state updates.
src/config.rs Multi-profile TOML config loader/saver; enforces 0600 perms on write.
src/state.rs TOML cache schema for user/semesters/courses/files plus helpers to read/write/mutate per profile.
src/paths.rs Resolves XDG-compliant config/data dirs with optional overrides.
src/studip_client.rs Thin JSON:API client (Basic auth header, pagination helper, download streaming).
src/semesters.rs Converts human semester titles (“WiSe 2024/25”) into stable keys (ws2425).
src/logging.rs Tracing subscriber setup with quiet/debug/json/verbosity knobs.
docs/studip/ Offline copy of Stud.IP JSON:API docs for reference (no code).

Runtime Flow

  1. studip-sync init-config writes a config template (optionally overriding download_root and guarded by --force).
  2. studip-sync auth collects credentials (CL flags, env, or interactive prompts), Base64-encodes username:password, and persists it in the active profile.
  3. studip-sync list-courses builds a StudipClient, resolves/caches the user ID via /users/me, paginates /users/{id}/courses, fetches missing semesters (including start/end timestamps and re-fetching cached semesters that lack them), upserts course metadata into state.toml, and prints a table sorted by semester/title.
  4. studip-sync sync:
    • Resolves download root (config.download_root or $XDG_DATA_HOME/studip-sync/downloads) and ensures directories exist unless --dry-run.
    • Refreshes course + semester info, then for each course performs a depth-first walk: /courses/{id}/folders/folders/{id}/file-refs/folders/{id}/folders. Pagination is handled by fetch_all_pages.
    • Normalizes path components and uses NameRegistry to avoid collisions, guaranteeing human-readable yet unique names.
    • Checks file state (size, modified timestamp, checksum) against state.toml to skip unchanged files; downloads stream to *.part before rename.
    • Records remote metadata + local path hints in state. --dry-run reports actions without touching disk; --prune (plus nondry-run) deletes stray files/dirs with walkdir.
    • --since <semester|date> now resolves either a semester key (e.g., ws2526) to its cached start timestamp or a date string (DDMMYY, DDMMYYYY, RFC3339) and skips remote files whose chdate precedes that cutoff.
  5. HTTP errors propagate via anyhow, but 401/403 currently surface as generic failures—production UX should point users to studip-sync auth.

Configuration & State

  • Config path: ${XDG_CONFIG_HOME:-~/.config}/studip-sync/config.toml. Override with --config-dir when needed. Example keys: base_url, jsonapi_path, basic_auth_b64, download_root, max_concurrent_downloads.
  • State path: ${XDG_DATA_HOME:-~/.local/share}/studip-sync/state.toml. --data-dir relocates this tree (and the default downloads/ folder). Explicitly setting download_root decouples downloads from the data dir; otherwise it defaults to <data-dir>/downloads.
    • profiles.<name>.user_id caches /users/me.
    • profiles.<name>.semesters.<key> stores semester IDs/titles/keys plus start/end timestamps (needed for --since ws2526). Running list-courses --refresh will also refresh already-known semesters missing those timestamps so sync --since … can resolve properly.
    • profiles.<name>.courses.<id> keeps display names + last_sync.
    • profiles.<name>.files.<file_ref_id> remembers size, checksum, timestamps, and the last local path to avoid redundant downloads.
  • Multiple profiles are supported; --profile switches, otherwise the configs default_profile is used.

Development Workflow

  1. Install a recent Rust toolchain (rustup toolchain install stable if needed).
  2. Lint/test loop:
    cargo fmt --all -- --check
    cargo clippy --all-targets --all-features -- -D warnings
    cargo test
    
  3. Use cargo run -- <subcommand> for manual verification (e.g., cargo run -- auth, cargo run -- list-courses --refresh, cargo run -- sync --dry-run).
  4. Keep dependencies minimal; avoid logging sensitive strings (basic_auth_b64, plaintext passwords).

Known Gaps / Backlog

  • ConfigProfile::max_concurrent_downloads is defined but unused; downloads happen sequentially. Introduce a bounded task queue if concurrency is needed.
  • Server-side filtering (filter[since], if supported) is not used yet. Local cutoff logic relies on Stud.IP timestamps; future work could add conditional API query parameters once officially documented.
  • No automated tests (unit/integration) are present; critical helpers like semesters::infer_key, normalize_component, and state transitions should gain coverage.
  • Error UX for auth failures could be clearer (detect 401/403 and prompt users to re-run auth).
  • There is no CI config; if one is added, ensure it runs fmt/clippy/test.
  • Verify long-term compatibility with Rust 2024 or document the minimum supported version explicitly.

Keep this guide updated whenever major flow or architecture changes land so that future agents can jump straight into implementation work.