Repository navigation
feat: one sharing vocabulary across pastes, workspaces and the audit log - #74
Conversation
The design doc collapses four overlapping sharing concepts into three settings that each read as a sentence: "Who can see this" on a paste, and "Sharing outside the team" and "Who can join" on a workspace. Add TextbinWeb.Sharing as the single place those words live, and move the paste editor, detail page and list onto it. Stored values (audience, external_sharing_policy, visibility) are unchanged: the API, the CLI and recorded audit metadata depend on them. - Badges read "Anyone with the link" instead of "Unlisted". - The detail sentence for a public paste says "Anyone can see this paste." - A forbidden audience in the editor names the workspace setting that turns it off. - Pastes.audience_allowed?/2 is now public so the editor disables options with the same rule the changeset enforces, instead of a copy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019fnjMN7WpEjQJD2zveakV6
…team" Replace the "Visibility" (Open/Private) and "External sharing" (Disabled/Unlisted links/Public) selects with the design doc's wording, and put a sentence under each that describes the option being considered. The form now re-renders on change so the sentence follows the selection before anything is saved. The sharing sentence states what tightening does to pastes that are already shared, because Organizations clamps their audience on save: "Members only" stops earlier links working and "Members may share a link" turns public pastes link-only. The design doc says tightening never changes existing pastes; the code does, and the wording follows the code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019fnjMN7WpEjQJD2zveakV6
Workspace lists, the new-workspace form and the organization overview say "Who can join: Invite only" or "Anyone in the organization" instead of the raw "open"/"private" value, with a building icon for open workspaces so the globe stays reserved for public pastes. Audit entries for these settings are titled "Who can join changed" and "Sharing outside the team changed" and describe the change with the same labels. Recorded metadata is unchanged, so older events render with the new words too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019fnjMN7WpEjQJD2zveakV6
Describe current access separately from admission: existing members keep access when a workspace becomes invite-only; owners add new members. Update LiveView sentence coverage. Verified 567 tests, Credo, and rendered private/open preview states.
|
Oracle review complete: signed off after correcting the invite-only workspace explanation. Existing members retain access, including those who self-joined while open; owners must add new members. No permissions, stored values, or audience-clamp behavior changed. The nearby comment now describes policy tightening on save rather than autosave. Validation: mix precommit (567 ExUnit tests plus JS tests), mix credo, and real Chromium checks of private settings and the unsaved open-policy preview passed. Both screenshots were inspected for readable wording/layout. Corrections committed and pushed without rewriting published history. Review session and visual artifacts: https://ampcode.com/threads/T-01a12594-e2f1-75be-b343-9239564f5c84 Post-push CI is green: memory/local/S3 Elixir tests, Rust tests, formatting/linting, and production-container build all passed. Release/publication jobs skipped as expected. |
## Summary This settles the doc-vs-code mismatch flagged in #74. `docs/design.md` said that tightening "Sharing outside the team" *never changes pastes already shared*. The code does the opposite at two layers: - **On save:** `Organizations.clamp_paste_audiences/1` rewrites existing audiences to fit the new setting. - **On every read:** shared-link access re-checks the workspace's current setting. The code's behaviour is the one to keep: - An owner who switches to "Members only", for example after a leak, needs links already shared to stop working. - Because the clamp rewrites stored audiences, loosening the setting later doesn't quietly re-share anything. The doc now describes that behaviour. The UI has said the same since #74. Doc-only change. No code changes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_019fnjMN7WpEjQJD2zveakV6 --- _Generated by [Claude Code](https://claude.ai/code/session_019fnjMN7WpEjQJD2zveakV6)_ Co-authored-by: Claude <noreply@anthropic.com>
Summary
The design doc's "Vocabulary" section reduces four overlapping sharing concepts to three settings. Each one reads as a sentence. This PR puts those words in the interface. Stored values are unchanged (
audience,external_sharing_policy,visibility), so the API, the CLI and existing audit metadata keep working.Commits
TextbinWeb.Sharingholds every label, sentence and icon. The paste editor, detail page and list now use it.Pastes.audience_allowed?/2is now public, so the editor disables options using the same rule the changeset enforces, not a copy of it.The doc says tightening "Sharing outside the team" never changes pastes already shared. The code does the opposite:
Organizations.clamp_paste_audiences/1downgrades existing pastes when the setting is saved. I kept the code's behaviour, because it's the safer default for an owner shutting off external access. The wording follows the code:Which one should win, the doc or the code? If the doc's behaviour is the intent, that change belongs in its own PR, together with a doc or code fix.
Test plan
mix test: 567 tests, 0 failures. New tests:Sharing.mix credoreports no issues.mix compile --warnings-as-errorsis clean.🤖 Generated with Claude Code
https://claude.ai/code/session_019fnjMN7WpEjQJD2zveakV6
Generated by Claude Code