The experiment Order No 2026 Add a new role: viewer. - Viewers can see accessible boards and cards on them - Viewers cannot be assigned to cards - Viewers can comment on cards but only on cards being triaged - Viewers cannot create cards or boards - Viewers has no access to other parts of the app - The restrictions hold even for user owned cards/comments Ensure there is no UI controls associated with actions not available to viewers.
admin member system ].index_by(&:itself), scopes: false end def can_change?(other) (admin? && !other.owner?) || other == self end def can_administer?(other) admin? && !other.owner? && other != self end def can_administer_board?(board) admin? || board.creator == self end def can_administer_card?(card) admin? || card.creator == self end end
(C1) Layered (C1) Base (C2) Layered (C2) Base (C3) Layered (C3) Controllers Models Views Policies ! [Base] Scattered guards: 27 controllers with before_action :ensure_contributor — each is a maintenance point for new endpoints
separation of concerns reduces review surface significantly Without clear boundaries, bug can escape even when using smarter AI workflows Layers demonstrate stronger compounding effect
▘▘ ▝▝ /Users/vladimirdementyev/dev/fizzy > /layered-rails:analyze • I'll run a comprehensive layered architecture analysis of the Fizzy codebase. Let me start by gathering structural information and running violation detection in parallel. • 3 Explore agents finished (ctrl+o to expand) ├─ Analyze model concerns/modules · 69 tool uses · 44.7k tokens │ 㽾 Done ├─ Analyze controllers for violations · 65 tool uses · 43.7k tokens │ 㽾 Done └─ Analyze jobs and helpers · 47 tool uses · 38.1k tokens 㽾 Done • Now I have all the data needed. Here's the full analysis:
tool uses · 38.1k tokens 㽾 Done • Now I have all the data needed. Here's the full analysis: --- Layered Architecture Analysis Summary - Overall health: Good - Layer compliance: ~90% - God object candidates: 1 (Card, via concern proliferation) - Callback concerns: 3 (minor) - Anti-patterns detected: 3 (minor) The Fizzy codebase demonstrates strong layered architecture discipline, consistent with Basecamp's "vanilla Rails" philosophy. Controllers are thin, models are rich, and side effects are well-organized. The most notable pattern is namespace-scoped concerns (e.g., Card::Closeable) rather than a flat app/models/concerns/ bag ....
describe "#process" do context "when import succeeds" do it "sets status to processing then completed" # ✅ Domain: state transition it "records started_at and completed_at" # ✅ Domain: state tracking it "delegates to Processor" # ✅ Domain: orchestration end context "when import fails" do it "sets status to failed with error message" # ✅ Domain: state transition it "re-raises the error" # ✅ Domain: error propagation end context "when system user does not exist" do it "creates a system user on the account" # ⚠ Belongs on Account — duplicates account.system_user end end # ... end
enqueues TrelloImportJob" # ✅ Domain test "process imports board from Trello JSON" # ⚠ Integration: runs full Processor, tests Processor behavior test "process imports columns from lists" # ⚠ Integration: same test "process imports cards" # ⚠ Integration: same # ... test "process sets status to failed on error" # ✅ Domain: state transition test "store_id_mapping and get_fizzy_id work correctly" # ✅ Domain: unit behavior test "accessible_to? returns true for owner"# ✅ Domain: unit behavior test "import with API credentials attempts attachment download" # ❌ Infrastructure: uses stub_request(:get, /trello\.com/) # ... end