[chore](trx-rs): remove implementation stub files
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
@@ -1,144 +0,0 @@
|
||||
//! HTTP auth implementation plan (draft)
|
||||
//!
|
||||
//! Scope: `trx-frontend-http` optional passphrase auth with roles:
|
||||
//! - `rx` (read-only)
|
||||
//! - `control` (read + mutating control)
|
||||
//!
|
||||
//! This is a planning artifact, not compiled runtime code.
|
||||
|
||||
/// Implementation phases in execution order.
|
||||
#[allow(dead_code)]
|
||||
pub enum Phase {
|
||||
ConfigModel,
|
||||
RuntimeState,
|
||||
AuthEndpoints,
|
||||
MiddlewareAuthorization,
|
||||
FrontendLoginGate,
|
||||
FrontendRoleGating,
|
||||
Testing,
|
||||
DocsAndExamples,
|
||||
}
|
||||
|
||||
/// High-level delivery checklist.
|
||||
#[allow(dead_code)]
|
||||
pub const CHECKLIST: &[&str] = &[
|
||||
"Add optional [frontends.http.auth] config (enabled default false)",
|
||||
"Support rx_passphrase/control_passphrase + tx_access_control_enabled",
|
||||
"Create in-memory session store with role + expiry",
|
||||
"Implement /auth/login, /auth/logout, /auth/session",
|
||||
"Add middleware for route protection and role enforcement",
|
||||
"Gate TX/PTT mutating routes when tx_access_control_enabled=true",
|
||||
"Update web app to show Access denied + login until authenticated",
|
||||
"Hide/disable TX/PTT controls for rx role",
|
||||
"Add unit + integration tests for role matrix",
|
||||
"Document behavior in README + config examples",
|
||||
];
|
||||
|
||||
/// Detailed plan per phase.
|
||||
#[allow(dead_code)]
|
||||
pub mod detailed_plan {
|
||||
/// Phase 1: config structs + parsing
|
||||
pub const CONFIG_MODEL: &[&str] = &[
|
||||
"Add HttpAuthConfig into client frontend config model:",
|
||||
" enabled: bool (default false)",
|
||||
" rx_passphrase: Option<String>",
|
||||
" control_passphrase: Option<String>",
|
||||
" tx_access_control_enabled: bool (default true)",
|
||||
" session_ttl_min: u64 (default 480)",
|
||||
" cookie_secure: bool (default false)",
|
||||
" cookie_same_site: enum/string (default Lax)",
|
||||
"Validation: if enabled=true, require at least one passphrase",
|
||||
"Validation: accept rx-only, control-only, or both",
|
||||
];
|
||||
|
||||
/// Phase 2: runtime auth state
|
||||
pub const RUNTIME_STATE: &[&str] = &[
|
||||
"Define AuthRole { Rx, Control }",
|
||||
"Define SessionRecord { role, issued_at, expires_at, last_seen }",
|
||||
"Create SessionStore = HashMap<SessionId, SessionRecord> + Mutex/RwLock",
|
||||
"Generate session IDs via cryptographically secure random bytes",
|
||||
"Add periodic expired-session cleanup task",
|
||||
"Attach auth state to Actix app_data in HTTP server builder",
|
||||
];
|
||||
|
||||
/// Phase 3: auth endpoints
|
||||
pub const AUTH_ENDPOINTS: &[&str] = &[
|
||||
"POST /auth/login body: { passphrase }",
|
||||
"Match control passphrase first, then rx passphrase",
|
||||
"Set HttpOnly session cookie trx_http_sid with TTL",
|
||||
"Response: { authenticated: true, role: \"rx\"|\"control\" }",
|
||||
"POST /auth/logout clears cookie + removes session",
|
||||
"GET /auth/session returns current auth state/role",
|
||||
"Do not log passphrase values",
|
||||
];
|
||||
|
||||
/// Phase 4: middleware + route authorization
|
||||
pub const MIDDLEWARE_AUTHZ: &[&str] = &[
|
||||
"Install middleware only when auth.enabled=true",
|
||||
"Public allowlist: /, static assets, /auth/*",
|
||||
"Protected read routes (rx/control): /status, /events, /decode, /audio",
|
||||
"Protected control routes (control only): all mutating POST routes",
|
||||
"On missing/invalid session: return 401",
|
||||
"On insufficient role: return 403 (or 404 for hidden TX/PTT policy)",
|
||||
"If tx_access_control_enabled=true: enforce hard block for TX/PTT endpoints for non-control",
|
||||
];
|
||||
|
||||
/// Phase 5: frontend login gate and default denied state
|
||||
pub const FRONTEND_LOGIN_GATE: &[&str] = &[
|
||||
"At app startup call /auth/session before connect()",
|
||||
"If unauthenticated: show logo + 'Access denied' view + passphrase form",
|
||||
"On login success: initialize streams/events and normal UI",
|
||||
"On 401/403 from API/SSE/WS: stop streams and return to denied/login view",
|
||||
"Add logout action in header/about",
|
||||
];
|
||||
|
||||
/// Phase 6: frontend role-specific UI policy
|
||||
pub const FRONTEND_ROLE_GATING: &[&str] = &[
|
||||
"If role=rx: hide/disable TX/PTT/mutating controls",
|
||||
"If role=control: show full controls",
|
||||
"When tx_access_control_enabled=true and role!=control:",
|
||||
" do not render PTT/TX controls at all",
|
||||
" do not expose action affordances in DOM where possible",
|
||||
];
|
||||
|
||||
/// Phase 7: tests
|
||||
pub const TESTS: &[&str] = &[
|
||||
"Unit: config validation for enabled/disabled + passphrase combinations",
|
||||
"Unit: session creation, lookup, expiry cleanup",
|
||||
"Unit: middleware path classification and role checks",
|
||||
"Integration: unauth /set_freq => 401",
|
||||
"Integration: rx login => /status 200, /set_ptt 403",
|
||||
"Integration: control login => /set_ptt 200",
|
||||
"Integration: tx_access_control_enabled=true => tx/ptt unavailable for rx",
|
||||
"Integration: auth disabled => legacy behavior unchanged",
|
||||
];
|
||||
|
||||
/// Phase 8: docs
|
||||
pub const DOCS: &[&str] = &[
|
||||
"Update trx-client.toml.example with [frontends.http.auth]",
|
||||
"Update README with optional auth behavior and role model",
|
||||
"Document security caveats: use TLS for non-local access",
|
||||
];
|
||||
}
|
||||
|
||||
/// Suggested file touch list (initial estimate).
|
||||
#[allow(dead_code)]
|
||||
pub const FILES_TO_TOUCH: &[&str] = &[
|
||||
"src/trx-client/src/config.rs (or equivalent client config model)",
|
||||
"trx-client.toml.example",
|
||||
"src/trx-client/trx-frontend/trx-frontend-http/src/server.rs",
|
||||
"src/trx-client/trx-frontend/trx-frontend-http/src/api.rs",
|
||||
"src/trx-client/trx-frontend/trx-frontend-http/src/audio.rs",
|
||||
"src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html",
|
||||
"src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js",
|
||||
"README.md",
|
||||
];
|
||||
|
||||
/// Rollout strategy.
|
||||
#[allow(dead_code)]
|
||||
pub const ROLLOUT: &[&str] = &[
|
||||
"Step 1: backend-only auth endpoints + middleware behind enabled flag",
|
||||
"Step 2: frontend login UX and role-aware UI",
|
||||
"Step 3: enforce TX/PTT hard-gate and tests",
|
||||
"Step 4: docs + example config",
|
||||
];
|
||||
@@ -1,161 +0,0 @@
|
||||
//! Decoder log files implementation plan (server-side)
|
||||
//!
|
||||
//! Goal:
|
||||
//! - Persist decoded messages to disk.
|
||||
//! - Split output by decoder name (APRS/CW/FT8/WSPR).
|
||||
//! - Make file names/paths configurable in `trx-server.toml`.
|
||||
//! - Keep runtime overhead low and avoid decoder stalls.
|
||||
//!
|
||||
//! This file is a planning artifact, not production code.
|
||||
|
||||
/// Ordered rollout phases.
|
||||
#[allow(dead_code)]
|
||||
pub enum Phase {
|
||||
ConfigSchema,
|
||||
RuntimeWriters,
|
||||
DecoderHookup,
|
||||
FileFormat,
|
||||
RotationAndRetention,
|
||||
ErrorHandling,
|
||||
Tests,
|
||||
Docs,
|
||||
}
|
||||
|
||||
/// MVP checklist.
|
||||
#[allow(dead_code)]
|
||||
pub const MVP_CHECKLIST: &[&str] = &[
|
||||
"Add [decode_logs] config section in trx-server config",
|
||||
"Add per-decoder output targets (aprs/cw/ft8/wspr)",
|
||||
"Implement async file writer worker(s)",
|
||||
"Emit one line per decoded event (JSONL)",
|
||||
"Hook writers into existing record/send points in audio.rs",
|
||||
"Ensure logger failures never crash decoder tasks",
|
||||
"Add tests for config parsing + file output",
|
||||
"Document usage in trx-server.toml.example + CONFIGURATION.md",
|
||||
];
|
||||
|
||||
/// Proposed config shape.
|
||||
#[allow(dead_code)]
|
||||
pub const CONFIG_PROPOSAL: &str = r#"
|
||||
[decode_logs]
|
||||
enabled = false
|
||||
format = "jsonl" # jsonl (initial MVP)
|
||||
flush_interval_ms = 250 # buffered flush interval
|
||||
create_dirs = true
|
||||
|
||||
[decode_logs.files]
|
||||
# Any omitted decoder uses default pattern in base_dir
|
||||
base_dir = "./logs/decoders"
|
||||
aprs = "aprs.log"
|
||||
cw = "cw.log"
|
||||
ft8 = "ft8.log"
|
||||
wspr = "wspr.log"
|
||||
|
||||
[decode_logs.rotation]
|
||||
enabled = false
|
||||
max_bytes = 10485760 # 10 MiB
|
||||
max_files = 10
|
||||
"#;
|
||||
|
||||
/// Config behavior rules.
|
||||
#[allow(dead_code)]
|
||||
pub const CONFIG_RULES: &[&str] = &[
|
||||
"If decode_logs.enabled=false, no file writers are started",
|
||||
"If enabled=true and path missing, use base_dir + '<name>.log'",
|
||||
"Paths may be absolute or relative to current working directory",
|
||||
"If create_dirs=true, create parent directories on startup",
|
||||
"Invalid paths -> startup warning + decoder logging disabled for that target",
|
||||
];
|
||||
|
||||
/// File layout / names strategy.
|
||||
#[allow(dead_code)]
|
||||
pub const NAMING_PLAN: &[&str] = &[
|
||||
"Split by decoder name: aprs/cw/ft8/wspr",
|
||||
"Allow custom names per decoder via [decode_logs.files]",
|
||||
"Support one shared directory + per-decoder file names",
|
||||
"Keep deterministic defaults to simplify ops and tailing",
|
||||
];
|
||||
|
||||
/// Runtime architecture.
|
||||
#[allow(dead_code)]
|
||||
pub const RUNTIME_ARCHITECTURE: &[&str] = &[
|
||||
"Create DecoderLogRouter with optional sender per decoder",
|
||||
"Spawn one async writer task per enabled decoder target",
|
||||
"Writer task receives already-serialized lines over bounded mpsc",
|
||||
"On backpressure/full queue: drop oldest/newest by policy + increment metric",
|
||||
"Periodic flush by timer; flush on shutdown signal",
|
||||
];
|
||||
|
||||
/// Where to hook in existing server code.
|
||||
#[allow(dead_code)]
|
||||
pub const INTEGRATION_POINTS: &[&str] = &[
|
||||
"src/trx-server/src/main.rs: initialize router from config before decoder tasks",
|
||||
"src/trx-server/src/audio.rs: after record_* and before/after decode_tx.send(...)",
|
||||
"APRS: record_aprs_packet path in run_aprs_decoder",
|
||||
"CW: event emission path in run_cw_decoder",
|
||||
"FT8: record_ft8_message path in run_ft8_decoder",
|
||||
"WSPR: record_wspr_message path in run_wspr_decoder",
|
||||
];
|
||||
|
||||
/// Line format (MVP JSONL).
|
||||
#[allow(dead_code)]
|
||||
pub const JSONL_SCHEMA: &[&str] = &[
|
||||
"ts_utc: RFC3339 timestamp generated at log write time",
|
||||
"decoder: one of aprs|cw|ft8|wspr",
|
||||
"rig_freq_hz: optional current RF base frequency",
|
||||
"payload: decoder-specific message object (existing serde struct)",
|
||||
"example: {\"ts_utc\":\"...\",\"decoder\":\"ft8\",\"payload\":{...}}",
|
||||
];
|
||||
|
||||
/// Rotation/retention plan (post-MVP but scoped).
|
||||
#[allow(dead_code)]
|
||||
pub const ROTATION_PLAN: &[&str] = &[
|
||||
"MVP can skip rotation if disabled",
|
||||
"If enabled: rotate file when size exceeds max_bytes",
|
||||
"Rename N->N+1, keep max_files, truncate/create active file",
|
||||
"Rotation performed inside writer task to avoid lock contention",
|
||||
];
|
||||
|
||||
/// Failure handling policy.
|
||||
#[allow(dead_code)]
|
||||
pub const FAILURE_POLICY: &[&str] = &[
|
||||
"Decoder pipeline must continue if file IO fails",
|
||||
"Log write failures with throttled warnings",
|
||||
"If a target becomes unavailable, retry reopen periodically",
|
||||
"Never panic from logger worker on malformed payload",
|
||||
];
|
||||
|
||||
/// Testing plan.
|
||||
#[allow(dead_code)]
|
||||
pub const TEST_PLAN: &[&str] = &[
|
||||
"Unit: config parse/default/validation for decode_logs",
|
||||
"Unit: per-decoder path resolution",
|
||||
"Unit: JSONL serializer output for each decoder type",
|
||||
"Integration: run decoder emit path and assert lines written to correct files",
|
||||
"Integration: disabled mode creates no files",
|
||||
"Integration: queue overflow policy counters/warnings",
|
||||
"Integration: rotation behavior when enabled",
|
||||
];
|
||||
|
||||
/// Files expected to change.
|
||||
#[allow(dead_code)]
|
||||
pub const FILES_TO_TOUCH: &[&str] = &[
|
||||
"src/trx-server/src/config.rs",
|
||||
"src/trx-server/src/main.rs",
|
||||
"src/trx-server/src/audio.rs",
|
||||
"src/trx-server/src/<new>/decode_logs.rs",
|
||||
"trx-server.toml.example",
|
||||
"CONFIGURATION.md",
|
||||
"tests under src/trx-server (unit/integration)",
|
||||
];
|
||||
|
||||
/// Implementation order recommendation.
|
||||
#[allow(dead_code)]
|
||||
pub const EXECUTION_ORDER: &[&str] = &[
|
||||
"1) Config + validation + defaults",
|
||||
"2) Minimal writer (single file, JSONL)",
|
||||
"3) Split-by-decoder routing",
|
||||
"4) Hook into APRS/CW/FT8/WSPR emit sites",
|
||||
"5) Add rotation/retention",
|
||||
"6) Add tests + docs",
|
||||
];
|
||||
Reference in New Issue
Block a user