Skip to content

feat: local-only schema fields (#166)#213

Merged
careck merged 19 commits into
developmentfrom
feat/166-local-only-fields
Jun 12, 2026
Merged

feat: local-only schema fields (#166)#213
careck merged 19 commits into
developmentfrom
feat/166-local-only-fields

Conversation

@careck

@careck careck commented Jun 10, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds local_only: true field property to Rhai schema definitions
  • UpdateField ops targeting local-only fields are dropped from sync deltas
  • CreateNote ops have local-only field values stripped before sync
  • Snapshot notes have local-only field values stripped
  • Export gains include_local_only option (checkbox in export dialog)
  • UI shows lock icon + "Local only" indicator on local-only fields
  • Documentation added to SCRIPTING.md
  • Full round-trip integration test covering all sync boundaries + export

Closes #166

Test plan

  • Create schema with local_only: true field — verify it parses and displays
  • Update a local-only field — verify value persists locally
  • Check operations_since — local-only UpdateField ops must not appear
  • Check CreateNote in sync — local-only field values must be stripped
  • Check snapshot — local-only field values must be stripped
  • Export with checkbox unchecked — local-only fields empty in archive
  • Export with checkbox checked — local-only fields present in archive
  • Import archive with local-only data — fields populate
  • Lock icon visible next to local-only field labels
  • Non-owner sees local-only indicator in read-only mode
  • All 7 locales have correct translations

careck added 19 commits June 10, 2026 13:55
- UpdateField ops targeting local-only fields dropped from operations_since
- CreateNote ops have local-only field values stripped
- Snapshot notes have local-only field values stripped
When exporting a workspace, local-only fields can now be stripped
from notes by passing include_local_only=false. The Tauri export
command exposes this as a new boolean parameter.
- Add localOnly: boolean to TypeScript FieldDefinition interface
- Add localOnlyHint i18n key to all 7 locale files (en, de, es, fr, ja, ko, zh)
- Show lock icon + hint text above local-only fields in edit mode (InfoPanel)
- Show lock icon next to field label in read-only mode (FieldDisplay)
- Covers top-level fields and field groups in both edit and view modes
Stripping local_only fields from CreateNote ops invalidated their Ed25519
signature, causing receivers to reject them (breaking attachment sync).
UpdateField filtering + snapshot stripping are sufficient for local-only
data protection. Also updates TextNote field count assertions for the new
my_notes field.
When a relay session expires, users can now click "Renew Session" in the
relay account dialog instead of deleting and recreating the account.
Uses stored credentials to re-authenticate automatically.
Sessions can be invalidated server-side before the local 30-day expiry
(server restart, concurrent login, admin action). Remove the
session_expires_at check from all 8 relay client build sites so
auto-login always runs when stored credentials are available.
The relay server rejects nanosecond-precision timestamps from chrono's
default to_rfc3339(). Switch to to_rfc3339_opts(SecondsFormat::Secs, true)
which produces clean "2026-06-19T05:23:45Z" format.
The previous "always auto-login" approach triggered rate limiting (429)
when multiple relay operations fired in quick succession. Restore the
expiry check but with a 5-minute buffer to proactively refresh sessions
approaching expiry while avoiding unnecessary login attempts.
…olling

When the relay server invalidates a session before the local expiry
timestamp, the 5-minute buffer proactive refresh doesn't help. Add
reactive retry logic to poll_receive_workspace: if ensure_mailbox
returns 401, re-login and rebuild the client before proceeding.

Also add proactive auto-login to poll_all_identity_snapshots which
previously used raw session tokens without any refresh logic.
The SyncEngine receives a RelayChannel at construction and uses it
internally for all relay operations. If the token is expired server-side,
every operation fails. Add a pre-flight ensure_mailbox check before
building the RelayChannel — if 401, re-login and use the fresh token.
After a successful retry-on-401 re-login, the new session token was only
used for the current poll cycle. The next cycle read the same stale token
from the RelayAccountManager, triggering another re-login attempt and
eventually hitting the rate limiter.

Now both poll_receive_workspace and poll_sync persist the refreshed token
via save_relay_account after re-login, so subsequent cycles use the fresh
token without re-authenticating.
@careck careck merged commit 3045328 into development Jun 12, 2026
2 checks passed
@careck careck deleted the feat/166-local-only-fields branch June 12, 2026 06:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant