Adds the first real screen: a setup form for the device's host/port,
tested against the real device (3 retries) and persisted to
preferences.toml before showing a placeholder "done" screen.
- Rust: test_connection/save_preferences/load_preferences commands;
preferences stored as [[reader]] in TOML so more readers can be
added later without a format change.
- Svelte: split the monolithic page into reusable components
(Screen, Column, Field, Button, ErrorBanner, Hint) under
src/lib/components, sharing design tokens from app.css.
- Automatic it/en i18n via svelte-i18n, locale detected from
navigator.language.
Assisted-by: Claude Sonnet 5 <noreply@anthropic.com>
Scaffolds the oxibadge crate/frontend as a new workspace member, stripped
down to a bare hello-world, and
extends the CI pipeline
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Moving the library into its own r701/ directory makes room for the
Tauri GUI client (Oxibadge) to be added as a sibling workspace member
in a following commit. edition/license/repository are now inherited
from the new workspace root instead of being duplicated per member.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- fake_records now generates a full year (2026) of classic workday
punches (09:00-13:00, 14:00-18:00) for the employees in fake_users;
this spans many 1024-byte blocks, exercising the multi-block
streaming path
- fake_users/fake_records are now public so tests can assert against
them instead of hardcoded expectations
- scoped #[allow(clippy::unwrap_used)] to only the functions that
actually use unwrap, instead of a blanket file-level allow
- added gets_total_record_count, streams_records, and
gets_none_for_unknown_employee tests
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
tests/mock/mod.rs emulates the device's TCP protocol (ping, get_name,
get_total_record_count, get_record_bytes), grounded in the reverse
engineering notes at
https://nicolabelluti.me/posts/2024/05/studying-a-communication-protocol/,
so tests/e2e.rs can exercise the real R701 client against it instead of
needing a physical reader. Starts with one test (connect + ping);
more scenarios (get_name, record streaming, error cases) to follow.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Added rustdoc comments to every public item (R701, Record, Clock,
RecordIterator and their methods/fields/variants), each with an
# Errors section where applicable, so the clippy::missing_errors_doc
allows are no longer needed.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- request() now reads exactly the expected response length with
read_exact instead of a single non-guaranteed fill_buf, fixing a
latent bug where a response split across multiple TCP packets could
be mistaken for malformed data; the per-method length checks are now
redundant and were removed
- sequence_number wraps explicitly via wrapping_add instead of
relying on implicit (and debug-vs-release inconsistent) overflow
behavior after 65536 requests
- get_name validates UTF-8 strictly instead of silently lossy-decoding
invalid bytes; on invalid data it now returns the FromUtf8Error
itself (byte-level \0 trimming moved after the UTF-8 check), letting
the caller choose to fail or fall back to a lossy rendering
- removed the unused Default derive from Clock and Record
- removed npm from the CI image (no JS/Node in this repo), fixed a
typo in a CI step name
- fixed the Cargo.toml license field to the actual SPDX identifier
(AGPL-3.0-or-later, per the notice at the end of LICENSE) instead of
the free-text "GNU AGPLv3.0"
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>