The tenanted db is the account scope
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
class Accounts::JoinCodesController < ApplicationController
|
||||
def show
|
||||
render svg: RQRCode::QRCode.new(join_url(Current.account.join_code)).as_svg(viewbox: true, fill: :white, color: :black)
|
||||
render svg: RQRCode::QRCode.new(join_url(Account.sole.join_code)).as_svg(viewbox: true, fill: :white, color: :black)
|
||||
end
|
||||
|
||||
def update
|
||||
Current.account.reset_join_code
|
||||
redirect_to account_users_path
|
||||
Account.sole.reset_join_code
|
||||
redirect_to users_path
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,22 +3,22 @@ class Accounts::UsersController < ApplicationController
|
||||
before_action :ensure_permission_to_administer_user, only: %i[ update destroy ]
|
||||
|
||||
def index
|
||||
@users = Current.account.users.active
|
||||
@users = User.active
|
||||
end
|
||||
|
||||
def update
|
||||
@user.update(role_params)
|
||||
redirect_to account_users_path
|
||||
redirect_to users_path
|
||||
end
|
||||
|
||||
def destroy
|
||||
@user.deactivate
|
||||
redirect_to account_users_path
|
||||
redirect_to users_path
|
||||
end
|
||||
|
||||
private
|
||||
def set_user
|
||||
@user = Current.account.users.active.find(params[:id])
|
||||
@user = User.active.find(params[:id])
|
||||
end
|
||||
|
||||
def ensure_permission_to_administer_user
|
||||
|
||||
@@ -3,7 +3,7 @@ class Cards::StagingsController < ApplicationController
|
||||
|
||||
def create
|
||||
if params[:stage_id].present?
|
||||
@card.toggle_stage Current.account.stages.find(params[:stage_id])
|
||||
@card.toggle_stage Stage.find(params[:stage_id])
|
||||
else
|
||||
@card.update!(stage: nil)
|
||||
end
|
||||
|
||||
@@ -2,7 +2,7 @@ class Cards::TaggingsController < ApplicationController
|
||||
include CardScoped
|
||||
|
||||
def new
|
||||
@tags = Current.account.tags.alphabetically
|
||||
@tags = Tag.alphabetically
|
||||
end
|
||||
|
||||
def create
|
||||
|
||||
@@ -11,6 +11,6 @@ class Collections::WorkflowsController < ApplicationController
|
||||
|
||||
private
|
||||
def set_workflow
|
||||
@workflow = Current.account.workflows.find(params.expect(collection: [ :workflow_id ]).require(:workflow_id))
|
||||
@workflow = Workflow.find(params.expect(collection: [ :workflow_id ]).require(:workflow_id))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,11 +2,11 @@ class CollectionsController < ApplicationController
|
||||
before_action :set_collection, except: %i[ new create ]
|
||||
|
||||
def new
|
||||
@collection = Current.account.collections.build
|
||||
@collection = Collection.new
|
||||
end
|
||||
|
||||
def create
|
||||
@collection = Current.account.collections.create! collection_params
|
||||
@collection = Collection.create! collection_params
|
||||
redirect_to cards_path(collection_ids: [ @collection ])
|
||||
end
|
||||
|
||||
@@ -37,7 +37,7 @@ class CollectionsController < ApplicationController
|
||||
end
|
||||
|
||||
def grantees
|
||||
Current.account.users.active.where id: grantee_ids
|
||||
User.active.where id: grantee_ids
|
||||
end
|
||||
|
||||
def revokees
|
||||
|
||||
@@ -29,7 +29,7 @@ module EventsTimeline
|
||||
end
|
||||
|
||||
def user_events
|
||||
Event.where(card: user_cards, creator: Current.account.users)
|
||||
Event.where(card: user_cards)
|
||||
end
|
||||
|
||||
def user_cards
|
||||
|
||||
@@ -7,6 +7,6 @@ module WorkflowScoped
|
||||
|
||||
private
|
||||
def set_workflow
|
||||
@workflow = Current.account.workflows.find params[:workflow_id]
|
||||
@workflow = Workflow.find(params[:workflow_id])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,7 +5,8 @@ class UploadsController < ApplicationController
|
||||
before_action :set_attachment, only: :show
|
||||
|
||||
def create
|
||||
@upload = Current.account.uploads_attachments.create! blob: create_blob!
|
||||
# FIXME: Try to get upload attachments on root
|
||||
@upload = Account.first.uploads_attachments.create! blob: create_blob!
|
||||
end
|
||||
|
||||
def show
|
||||
|
||||
@@ -24,7 +24,7 @@ class Users::AvatarsController < ApplicationController
|
||||
end
|
||||
|
||||
def set_user
|
||||
@user = Current.account.users.find(params[:user_id])
|
||||
@user = User.find(params[:user_id])
|
||||
end
|
||||
|
||||
def render_avatar_or_initials
|
||||
|
||||
@@ -5,11 +5,11 @@ class UsersController < ApplicationController
|
||||
before_action :set_account_from_join_code, only: %i[ new create ]
|
||||
|
||||
def new
|
||||
@user = @account.users.build
|
||||
@user = User.new
|
||||
end
|
||||
|
||||
def create
|
||||
user = @account.users.create!(user_params)
|
||||
user = User.create!(user_params)
|
||||
start_new_session_for user
|
||||
redirect_to root_path
|
||||
end
|
||||
@@ -21,8 +21,8 @@ class UsersController < ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
@user.update user_params
|
||||
redirect_to user_path(@user)
|
||||
@user.update! user_params
|
||||
redirect_to @user
|
||||
end
|
||||
|
||||
private
|
||||
@@ -31,7 +31,7 @@ class UsersController < ApplicationController
|
||||
end
|
||||
|
||||
def set_user
|
||||
@user = Current.account.users.active.find(params[:id])
|
||||
@user = User.active.find(params[:id])
|
||||
end
|
||||
|
||||
def user_params
|
||||
|
||||
@@ -2,15 +2,15 @@ class WorkflowsController < ApplicationController
|
||||
before_action :set_workflow, only: %i[ show edit update destroy ]
|
||||
|
||||
def index
|
||||
@workflows = Current.account.workflows
|
||||
@workflows = Workflow.all
|
||||
end
|
||||
|
||||
def new
|
||||
@workflow = Current.account.workflows.new
|
||||
@workflow = Workflow.new
|
||||
end
|
||||
|
||||
def create
|
||||
@workflow = Current.account.workflows.create! workflow_params
|
||||
@workflow = Workflow.create! workflow_params
|
||||
# FIXME: this should definitely change.
|
||||
[ "Triage", "In progress", "On Hold", "Review" ].each { |name| @workflow.stages.create! name: name }
|
||||
redirect_to workflows_path
|
||||
@@ -34,10 +34,10 @@ class WorkflowsController < ApplicationController
|
||||
|
||||
private
|
||||
def set_workflow
|
||||
@workflow = Current.account.workflows.find params[:id]
|
||||
@workflow = Workflow.find params[:id]
|
||||
end
|
||||
|
||||
def workflow_params
|
||||
params.expect workflow: [ :name ]
|
||||
params.expect workflow: :name
|
||||
end
|
||||
end
|
||||
|
||||
+1
-17
@@ -1,21 +1,5 @@
|
||||
class Account < ApplicationRecord
|
||||
include ClosureReasons, Joinable
|
||||
|
||||
has_many :collections, dependent: :destroy
|
||||
has_many :cards, through: :collections
|
||||
|
||||
has_many :users, dependent: :destroy do
|
||||
def system
|
||||
find_or_create_system_user(proxy_association.owner)
|
||||
end
|
||||
end
|
||||
|
||||
has_many :comments, through: :users
|
||||
|
||||
has_many :workflows, dependent: :destroy
|
||||
has_many :stages, through: :workflows, class_name: "Workflow::Stage"
|
||||
|
||||
has_many :tags, dependent: :destroy
|
||||
include Joinable
|
||||
|
||||
has_many_attached :uploads
|
||||
end
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
module Account::ClosureReasons
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
DEFAULT_LABELS = [
|
||||
"Completed",
|
||||
"Duplicate",
|
||||
"Maybe later",
|
||||
"Working as intended"
|
||||
]
|
||||
|
||||
FALLBACK_LABEL = "Done"
|
||||
|
||||
included do
|
||||
has_many :closure_reasons, dependent: :destroy, class_name: "Closure::Reason" do
|
||||
def labels
|
||||
pluck(:label).presence || [ FALLBACK_LABEL ]
|
||||
end
|
||||
end
|
||||
|
||||
after_create :create_default_closure_reasons
|
||||
end
|
||||
|
||||
private
|
||||
def create_default_closure_reasons
|
||||
DEFAULT_LABELS.each do |label|
|
||||
closure_reasons.create! label: label
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -16,7 +16,7 @@ module Card::Closeable
|
||||
class_methods do
|
||||
def auto_close_all_due
|
||||
due_to_be_closed.find_each do |card|
|
||||
card.close(user: card.collection.account.users.system, reason: "Closed")
|
||||
card.close(user: User.system, reason: "Closed")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -41,7 +41,7 @@ module Card::Closeable
|
||||
closure&.created_at
|
||||
end
|
||||
|
||||
def close(user: Current.user, reason: Account::ClosureReasons::FALLBACK_LABEL)
|
||||
def close(user: Current.user, reason: Closure::Reason::FALLBACK_LABEL)
|
||||
unless closed?
|
||||
transaction do
|
||||
create_closure! user: user, reason: reason
|
||||
|
||||
@@ -9,7 +9,7 @@ module Card::Taggable
|
||||
end
|
||||
|
||||
def toggle_tag_with(title)
|
||||
tag = collection.account.tags.find_or_create_by!(title: title)
|
||||
tag = Tag.find_or_create_by!(title: title)
|
||||
|
||||
transaction do
|
||||
if tagged_with?(tag)
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
class Closure::Reason < ApplicationRecord
|
||||
belongs_to :account
|
||||
DEFAULT_LABELS = [
|
||||
"Completed",
|
||||
"Duplicate",
|
||||
"Maybe later",
|
||||
"Working as intended"
|
||||
]
|
||||
|
||||
FALLBACK_LABEL = "Done"
|
||||
|
||||
class << self
|
||||
def labels
|
||||
pluck(:label).presence || [ FALLBACK_LABEL ]
|
||||
end
|
||||
|
||||
def create_defaults
|
||||
DEFAULT_LABELS.each do |label|
|
||||
create! label: label
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
class Collection < ApplicationRecord
|
||||
include Accessible, Broadcastable, Filterable
|
||||
|
||||
belongs_to :account
|
||||
belongs_to :creator, class_name: "User", default: -> { Current.user }
|
||||
belongs_to :workflow, optional: true
|
||||
|
||||
|
||||
@@ -34,6 +34,6 @@ module Collection::Accessible
|
||||
|
||||
private
|
||||
def grant_access_to_everyone
|
||||
accesses.grant_to(account.users) if all_access_previously_changed?(to: true)
|
||||
accesses.grant_to(User.all) if all_access_previously_changed?(to: true)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,6 +3,6 @@ module Collection::Broadcastable
|
||||
|
||||
included do
|
||||
broadcasts_refreshes
|
||||
broadcasts_refreshes_to ->(collection) { [ collection.account, :collections ] }
|
||||
broadcasts_refreshes_to ->(collection) { :collections }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,5 +2,4 @@ class Current < ActiveSupport::CurrentAttributes
|
||||
attribute :session
|
||||
|
||||
delegate :user, to: :session, allow_nil: true
|
||||
delegate :account, to: :user, allow_nil: true
|
||||
end
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
class FirstRun
|
||||
def self.create!(user_attributes)
|
||||
account = Account.create!(name: "Fizzy")
|
||||
account.users.member.create!(user_attributes)
|
||||
Account.create!(name: "Fizzy")
|
||||
User.member.create!(user_attributes)
|
||||
Closure::Reason.create_defaults
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
class Tag < ApplicationRecord
|
||||
include Filterable
|
||||
|
||||
belongs_to :account, default: -> { Current.account }, touch: true
|
||||
|
||||
has_many :taggings, dependent: :destroy
|
||||
has_many :cards, through: :taggings
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
class User < ApplicationRecord
|
||||
include Accessor, Assignee, Avatar, Role, Transferable
|
||||
|
||||
belongs_to :account
|
||||
|
||||
has_many :sessions, dependent: :destroy
|
||||
has_secure_password validations: false
|
||||
|
||||
|
||||
@@ -11,6 +11,6 @@ module User::Accessor
|
||||
|
||||
private
|
||||
def grant_access_to_collections
|
||||
Access.insert_all account.collections.all_access.pluck(:id).collect { |collection_id| { collection_id: collection_id, user_id: id } }
|
||||
Access.insert_all Collection.all_access.pluck(:id).collect { |collection_id| { collection_id: collection_id, user_id: id } }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,10 +10,8 @@ module User::Role
|
||||
end
|
||||
|
||||
class_methods do
|
||||
def find_or_create_system_user(account)
|
||||
account.users.find_or_create_by!(role: :system) do |user|
|
||||
user.name = "System"
|
||||
end
|
||||
def system
|
||||
find_or_create_by!(role: :system) { it.name = "System" }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
class Workflow < ApplicationRecord
|
||||
belongs_to :account
|
||||
has_many :stages, dependent: :delete_all
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="flex flex-column align-center gap">
|
||||
<% url = join_url(Current.account.join_code) %>
|
||||
<% url = join_url(Account.sole.join_code) %>
|
||||
|
||||
<label class="flex flex-column gap full-width txt-align-center">
|
||||
<strong id="invite_label" class="invite-label">Share to invite more people</strong>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<%= icon_tag "caret-down" %>
|
||||
</summary>
|
||||
<div class="expander__content btn borderless">
|
||||
<% Current.account.closure_reasons.labels.each do |label| %>
|
||||
<% Closure::Reason.labels.each do |label| %>
|
||||
<%= button_to card_closure_path(card, reason: label), class: "expander__item btn" do %>
|
||||
<span class="overflow-ellipsis"><%= label %></span>
|
||||
<% end %>
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
<strong class="txt-large">Choose a workflow</strong>
|
||||
<p class="margin-none">Use a workflow to track progress in this collection.</p>
|
||||
<%= form_with model: @collection, url: collection_workflow_path(@collection), local: true, method: :patch, data: { controller: "form" } do |form| %>
|
||||
<%= form.select :workflow_id, Current.account.workflows.map { |w| [w.name, w.id] }, { include_blank: "Choose…" }, class: "input input--select full-width", data: { action: "change->form#submit" } %>
|
||||
<%= form.select :workflow_id, Workflow.all.map { |w| [w.name, w.id] }, { include_blank: "Choose…" }, class: "input input--select full-width", data: { action: "change->form#submit" } %>
|
||||
<% end %>
|
||||
<p><%= link_to "Manage workflows", workflows_path, class: "btn btn--plain txt-link" %></p>
|
||||
</div>
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
<div class="btn btn--circle btn--placeholder flex-item-justify-start"></div>
|
||||
|
||||
<div class="events__index-header flex-inline flex-column center gap-half margin-block-end-double txt-align-center">
|
||||
<h2 class="txt-large txt-nowrap center"><%= Current.account.name %> / Latest activity</h2>
|
||||
<h2 class="txt-large txt-nowrap center"><%= Account.sole.name %> / Latest activity</h2>
|
||||
<%= render "events/filter" %>
|
||||
</div>
|
||||
|
||||
<%= link_to account_users_path, class: "btn flex-item-justify-end" do %>
|
||||
<%= link_to users_path, class: "btn flex-item-justify-end" do %>
|
||||
<%= icon_tag "settings" %>
|
||||
<span class="for-screen-reader">Account settings</span>
|
||||
<% end %>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<%= icon_tag "check", class: "checked flex-item-justify-end" %>
|
||||
</div>
|
||||
|
||||
<% Current.account.users.active.order(:name).each do |user| %>
|
||||
<% User.active.order(:name).each do |user| %>
|
||||
<div class="btn popup__item">
|
||||
<%= form.check_box "assignee_ids[]", {
|
||||
checked: filter.assignees.include?(user),
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
<%= turbo_stream_from collection %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= turbo_stream_from Current.account, :collections %>
|
||||
<%= turbo_stream_from :collections %>
|
||||
<% end %>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<%= icon_tag "check", class: "checked flex-item-justify-end" %>
|
||||
</div>
|
||||
|
||||
<% Current.account.users.active.without(Current.user).order(:name).each do |user| %>
|
||||
<% User.active.without(Current.user).order(:name).each do |user| %>
|
||||
<div class="btn popup__item">
|
||||
<%= form.check_box :creator_ids, {
|
||||
multiple: true,
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
<% end %>
|
||||
</menu>
|
||||
|
||||
<% if workflow = Current.account.workflows.first %>
|
||||
<% if workflow = Workflow.first %>
|
||||
<menu class="filter__menu">
|
||||
<li class="filter__label"><strong>In Stage</strong></li>
|
||||
<% workflow.stages.each do |stage| %>
|
||||
@@ -93,7 +93,7 @@
|
||||
</menu>
|
||||
<% end %>
|
||||
|
||||
<% if (tags = Current.account.tags.order(:title)).any? %>
|
||||
<% if (tags = Tag.all.order(:title)).any? %>
|
||||
<div class="filter__menu" role="group" aria-label="Tagged">
|
||||
<div class="filter__label"><strong>Tagged</strong></div>
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<% Current.account.users.active.without(Current.user).order(:name).each do |user| %>
|
||||
<% User.active.without(Current.user).order(:name).each do |user| %>
|
||||
<div>
|
||||
<label class="btn filter__button">
|
||||
<%= check_box_tag "assignee_ids[]", user.id, filter.assignees.include?(user), class: "visually-hidden",
|
||||
@@ -157,7 +157,7 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<% Current.account.users.active.without(Current.user).order(:name).each do |user| %>
|
||||
<% User.active.without(Current.user).order(:name).each do |user| %>
|
||||
<div>
|
||||
<label class="btn filter__button">
|
||||
<%= check_box_tag "creator_ids[]", user.id, filter.creators.include?(user), class: "visually-hidden" %>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<% if Current.account.workflows.any? %>
|
||||
<% if Workflow.any? %>
|
||||
<div class="quick-filter position-relative" data-controller="dialog" data-action="keydown.esc->dialog#close click@document->dialog#closeOnClickOutside">
|
||||
<button class="btn input input--select flex-inline txt-small" data-action="click->dialog#open:stop">
|
||||
<span class="overflow-ellipsis">
|
||||
@@ -20,8 +20,7 @@
|
||||
<%= filter_hidden_field_tag key, value %>
|
||||
<% end %>
|
||||
|
||||
<% workflow = Current.account.workflows.first %>
|
||||
<% workflow.stages.each do |stage| %>
|
||||
<% Workflow.first.stages.each do |stage| %>
|
||||
<div class="btn popup__item">
|
||||
<%= form.check_box :stage_ids, {
|
||||
multiple: true,
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<span class="overflow-ellipsis">Clear all</span>
|
||||
<% end %>
|
||||
|
||||
<% Current.account.tags.order(:title).each do |tag| %>
|
||||
<% Tag.order(:title).each do |tag| %>
|
||||
<div class="btn popup__item">
|
||||
<%= form.check_box "tag_ids[]", {
|
||||
checked: filter.tags.include?(tag),
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<% content_for :header do %>
|
||||
<nav>
|
||||
<%= link_to_back fallback_path: account_users_path %>
|
||||
<%= link_to_back fallback_path: users_path %>
|
||||
|
||||
<span class="btn btn--placeholder"></span>
|
||||
|
||||
|
||||
+3
-4
@@ -2,12 +2,11 @@ Rails.application.routes.draw do
|
||||
resource :first_run
|
||||
|
||||
resource :account do
|
||||
scope module: :accounts do
|
||||
resource :join_code
|
||||
resources :users
|
||||
end
|
||||
resource :join_code, module: :accounts
|
||||
end
|
||||
|
||||
resources :users
|
||||
|
||||
resources :collections do
|
||||
scope module: :collections do
|
||||
resource :subscriptions
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
class RemoveAccountIds < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
remove_column :closure_reasons, :account_id
|
||||
remove_column :collections, :account_id
|
||||
remove_column :tags, :account_id
|
||||
remove_column :users, :account_id
|
||||
remove_column :workflows, :account_id
|
||||
end
|
||||
end
|
||||
Generated
+1
-13
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.1].define(version: 2025_04_12_162339) do
|
||||
ActiveRecord::Schema[8.1].define(version: 2025_04_12_170620) do
|
||||
create_table "accesses", force: :cascade do |t|
|
||||
t.integer "collection_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
@@ -129,11 +129,9 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_12_162339) do
|
||||
end
|
||||
|
||||
create_table "closure_reasons", force: :cascade do |t|
|
||||
t.integer "account_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.string "label"
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["account_id"], name: "index_closure_reasons_on_account_id"
|
||||
end
|
||||
|
||||
create_table "closures", force: :cascade do |t|
|
||||
@@ -148,14 +146,12 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_12_162339) do
|
||||
end
|
||||
|
||||
create_table "collections", force: :cascade do |t|
|
||||
t.integer "account_id", null: false
|
||||
t.boolean "all_access", default: false, null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "creator_id", null: false
|
||||
t.string "name", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "workflow_id"
|
||||
t.index ["account_id"], name: "index_collections_on_account_id"
|
||||
t.index ["creator_id"], name: "index_collections_on_creator_id"
|
||||
t.index ["workflow_id"], name: "index_collections_on_workflow_id"
|
||||
end
|
||||
@@ -287,15 +283,12 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_12_162339) do
|
||||
end
|
||||
|
||||
create_table "tags", force: :cascade do |t|
|
||||
t.integer "account_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "title"
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["account_id"], name: "index_tags_on_account_id"
|
||||
end
|
||||
|
||||
create_table "users", force: :cascade do |t|
|
||||
t.integer "account_id", null: false
|
||||
t.boolean "active", default: true, null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "email_address"
|
||||
@@ -303,7 +296,6 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_12_162339) do
|
||||
t.string "password_digest"
|
||||
t.string "role", default: "member", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["account_id"], name: "index_users_on_account_id"
|
||||
t.index ["email_address"], name: "index_users_on_email_address", unique: true
|
||||
t.index ["role"], name: "index_users_on_role"
|
||||
end
|
||||
@@ -328,11 +320,9 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_12_162339) do
|
||||
end
|
||||
|
||||
create_table "workflows", force: :cascade do |t|
|
||||
t.integer "account_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "name", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["account_id"], name: "index_workflows_on_account_id"
|
||||
end
|
||||
|
||||
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
||||
@@ -353,11 +343,9 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_12_162339) do
|
||||
add_foreign_key "sessions", "users"
|
||||
add_foreign_key "taggings", "cards"
|
||||
add_foreign_key "taggings", "tags"
|
||||
add_foreign_key "users", "accounts"
|
||||
add_foreign_key "watches", "cards"
|
||||
add_foreign_key "watches", "users"
|
||||
add_foreign_key "workflow_stages", "workflows"
|
||||
add_foreign_key "workflows", "accounts"
|
||||
|
||||
# Virtual tables defined in this database.
|
||||
# Note that virtual tables may not work with other database engines. Be careful if changing database.
|
||||
|
||||
+12
-115
@@ -463,7 +463,7 @@ columns:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- &33 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
- &32 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: title
|
||||
cast_type: *7
|
||||
@@ -486,16 +486,6 @@ columns:
|
||||
comment:
|
||||
closure_reasons:
|
||||
- *5
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: account_id
|
||||
cast_type: *1
|
||||
sql_type_metadata: *2
|
||||
'null': true
|
||||
default:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: label
|
||||
@@ -535,24 +525,14 @@ columns:
|
||||
comment:
|
||||
collections:
|
||||
- *5
|
||||
- &32 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: account_id
|
||||
cast_type: *1
|
||||
sql_type_metadata: *2
|
||||
'null': false
|
||||
default:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: all_access
|
||||
cast_type: &34 !ruby/object:ActiveModel::Type::Boolean
|
||||
cast_type: &33 !ruby/object:ActiveModel::Type::Boolean
|
||||
precision:
|
||||
scale:
|
||||
limit:
|
||||
sql_type_metadata: &35 !ruby/object:ActiveRecord::ConnectionAdapters::SqlTypeMetadata
|
||||
sql_type_metadata: &34 !ruby/object:ActiveRecord::ConnectionAdapters::SqlTypeMetadata
|
||||
sql_type: boolean
|
||||
type: :boolean
|
||||
limit:
|
||||
@@ -860,18 +840,16 @@ columns:
|
||||
- *9
|
||||
tags:
|
||||
- *5
|
||||
- *32
|
||||
- *6
|
||||
- *33
|
||||
- *32
|
||||
- *9
|
||||
users:
|
||||
- *5
|
||||
- *32
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: active
|
||||
cast_type: *34
|
||||
sql_type_metadata: *35
|
||||
cast_type: *33
|
||||
sql_type_metadata: *34
|
||||
'null': false
|
||||
default: true
|
||||
default_function:
|
||||
@@ -919,8 +897,8 @@ columns:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: watching
|
||||
cast_type: *34
|
||||
sql_type_metadata: *35
|
||||
cast_type: *33
|
||||
sql_type_metadata: *34
|
||||
'null': false
|
||||
default: true
|
||||
default_function:
|
||||
@@ -953,7 +931,6 @@ columns:
|
||||
comment:
|
||||
workflows:
|
||||
- *5
|
||||
- *32
|
||||
- *6
|
||||
- *10
|
||||
- *9
|
||||
@@ -1421,23 +1398,7 @@ indexes:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
closure_reasons:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: closure_reasons
|
||||
name: index_closure_reasons_on_account_id
|
||||
unique: false
|
||||
columns:
|
||||
- account_id
|
||||
lengths: {}
|
||||
orders: {}
|
||||
opclasses: {}
|
||||
where:
|
||||
type:
|
||||
using:
|
||||
include:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
closure_reasons: []
|
||||
closures:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: closures
|
||||
@@ -1489,22 +1450,6 @@ indexes:
|
||||
comment:
|
||||
valid: true
|
||||
collections:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: collections
|
||||
name: index_collections_on_account_id
|
||||
unique: false
|
||||
columns:
|
||||
- account_id
|
||||
lengths: {}
|
||||
orders: {}
|
||||
opclasses: {}
|
||||
where:
|
||||
type:
|
||||
using:
|
||||
include:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: collections
|
||||
name: index_collections_on_creator_id
|
||||
@@ -1994,23 +1939,7 @@ indexes:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
tags:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: tags
|
||||
name: index_tags_on_account_id
|
||||
unique: false
|
||||
columns:
|
||||
- account_id
|
||||
lengths: {}
|
||||
orders: {}
|
||||
opclasses: {}
|
||||
where:
|
||||
type:
|
||||
using:
|
||||
include:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
tags: []
|
||||
users:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: users
|
||||
@@ -2044,22 +1973,6 @@ indexes:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: users
|
||||
name: index_users_on_account_id
|
||||
unique: false
|
||||
columns:
|
||||
- account_id
|
||||
lengths: {}
|
||||
orders: {}
|
||||
opclasses: {}
|
||||
where:
|
||||
type:
|
||||
using:
|
||||
include:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
watches:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: watches
|
||||
@@ -2110,21 +2023,5 @@ indexes:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
workflows:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: workflows
|
||||
name: index_workflows_on_account_id
|
||||
unique: false
|
||||
columns:
|
||||
- account_id
|
||||
lengths: {}
|
||||
orders: {}
|
||||
opclasses: {}
|
||||
where:
|
||||
type:
|
||||
using:
|
||||
include:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
version: 20250412162339
|
||||
workflows: []
|
||||
version: 20250412170620
|
||||
|
||||
@@ -10,7 +10,7 @@ Current.session = user.sessions.last
|
||||
workflow = account.workflows.first
|
||||
|
||||
COLLECTIONS_COUNT.times do |collection_index|
|
||||
collection = account.collections.create!(name: "Collection #{collection_index}", creator: user, workflow: workflow)
|
||||
collection = Collection.create!(name: "Collection #{collection_index}", creator: user, workflow: workflow)
|
||||
CARDS_PER_COLLECTION.times do |card_index|
|
||||
collection.cards.create!(title: "Card #{card_index}", creator: user, status: :published)
|
||||
end
|
||||
|
||||
@@ -4,9 +4,9 @@ CARDS_COUNT = 200
|
||||
|
||||
ApplicationRecord.current_tenant = "development-tenant"
|
||||
account = Account.first
|
||||
user = account.users.first
|
||||
user = User.first
|
||||
Current.session = user.sessions.last
|
||||
collection = account.collections.first
|
||||
collection = Collection.first
|
||||
|
||||
# Doing
|
||||
|
||||
|
||||
@@ -8,34 +8,34 @@ class Accounts::UsersControllerTest < ActionDispatch::IntegrationTest
|
||||
test "update" do
|
||||
assert_not users(:david).admin?
|
||||
|
||||
put account_user_url(users(:david)), params: { user: { role: "admin" } }
|
||||
put user_url(users(:david)), params: { user: { role: "admin" } }
|
||||
|
||||
assert_redirected_to account_users_path
|
||||
assert_redirected_to users_path
|
||||
assert users(:david).reload.admin?
|
||||
end
|
||||
|
||||
test "can't promote to special roles" do
|
||||
assert_no_changes -> { users(:david).reload.role } do
|
||||
put account_user_url(users(:david)), params: { user: { role: "system" } }
|
||||
put user_url(users(:david)), params: { user: { role: "system" } }
|
||||
end
|
||||
end
|
||||
|
||||
test "destroy" do
|
||||
assert_difference -> { User.active.count }, -1 do
|
||||
delete account_user_url(users(:david))
|
||||
delete user_url(users(:david))
|
||||
end
|
||||
|
||||
assert_redirected_to account_users_path
|
||||
assert_redirected_to users_path
|
||||
assert_nil User.active.find_by(id: users(:david).id)
|
||||
end
|
||||
|
||||
test "non-admins cannot perform actions" do
|
||||
sign_in_as :jz
|
||||
|
||||
put account_user_url(users(:david)), params: { user: { role: "admin" } }
|
||||
put user_url(users(:david)), params: { user: { role: "admin" } }
|
||||
assert_response :forbidden
|
||||
|
||||
delete account_user_url(users(:david))
|
||||
delete user_url(users(:david))
|
||||
assert_response :forbidden
|
||||
end
|
||||
end
|
||||
|
||||
@@ -43,7 +43,7 @@ class CollectionsControllerTest < ActionDispatch::IntegrationTest
|
||||
|
||||
test "update all access" do
|
||||
collection = Current.set(session: sessions(:kevin)) do
|
||||
accounts("37s").collections.create! name: "New collection", all_access: false
|
||||
Collection.create! name: "New collection", all_access: false
|
||||
end
|
||||
assert_equal [ users(:kevin) ], collection.users
|
||||
|
||||
@@ -51,7 +51,7 @@ class CollectionsControllerTest < ActionDispatch::IntegrationTest
|
||||
|
||||
assert_redirected_to cards_path(collection_ids: [ collection ])
|
||||
assert collection.reload.all_access?
|
||||
assert_equal accounts("37s").users, collection.users
|
||||
assert_equal User.all, collection.users
|
||||
end
|
||||
|
||||
test "destroy" do
|
||||
|
||||
Vendored
-1
@@ -1,6 +1,5 @@
|
||||
writebook:
|
||||
name: Writebook
|
||||
account: 37s
|
||||
creator: david
|
||||
all_access: true
|
||||
workflow: qa
|
||||
|
||||
Vendored
-2
@@ -1,7 +1,5 @@
|
||||
web:
|
||||
account: 37s
|
||||
title: web
|
||||
|
||||
mobile:
|
||||
account: 37s
|
||||
title: mobile
|
||||
|
||||
Vendored
-3
@@ -1,21 +1,18 @@
|
||||
<% digest = BCrypt::Password.create("secret123456") %>
|
||||
|
||||
david:
|
||||
account: 37s
|
||||
name: David
|
||||
email_address: david@37signals.com
|
||||
password_digest: <%= digest %>
|
||||
role: member
|
||||
|
||||
jz:
|
||||
account: 37s
|
||||
name: JZ
|
||||
email_address: jz@37signals.com
|
||||
password_digest: <%= digest %>
|
||||
role: member
|
||||
|
||||
kevin:
|
||||
account: 37s
|
||||
name: Kevin
|
||||
email_address: kevin@37signals.com
|
||||
password_digest: <%= digest %>
|
||||
|
||||
Vendored
-2
@@ -1,7 +1,5 @@
|
||||
qa:
|
||||
account: 37s
|
||||
name: QA
|
||||
|
||||
on_call:
|
||||
account: 37s
|
||||
name: "On call"
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
require "test_helper"
|
||||
|
||||
class ClosureReasonsTest < ActiveSupport::TestCase
|
||||
test "create defaults closure reasons on creation" do
|
||||
account = Account.create! name: "Rails"
|
||||
assert_equal Account::ClosureReasons::DEFAULT_LABELS, account.closure_reasons.pluck(:label)
|
||||
end
|
||||
end
|
||||
@@ -54,7 +54,7 @@ class CardTest < ActiveSupport::TestCase
|
||||
end
|
||||
assert cards(:logo).tagged_with?(tags(:web))
|
||||
|
||||
assert_difference %w[ cards(:logo).taggings.count accounts("37s").tags.count ], +1 do
|
||||
assert_difference %w[ cards(:logo).taggings.count Tag.count ], +1 do
|
||||
cards(:logo).toggle_tag_with "prioritized"
|
||||
end
|
||||
assert_equal "prioritized", cards(:logo).taggings.last.tag.title
|
||||
@@ -87,7 +87,7 @@ class CardTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test "in collection" do
|
||||
new_collection = accounts("37s").collections.create! name: "New Collection", creator: users(:david)
|
||||
new_collection = Collection.create! name: "New Collection", creator: users(:david)
|
||||
assert_equal cards(:logo, :shipping, :layout, :text), Card.in_collection(collections(:writebook))
|
||||
assert_empty Card.in_collection(new_collection)
|
||||
end
|
||||
|
||||
@@ -16,18 +16,18 @@ class CollectionTest < ActiveSupport::TestCase
|
||||
|
||||
test "grants access to everyone after creation" do
|
||||
collection = Current.set(session: sessions(:david)) do
|
||||
accounts("37s").collections.create! name: "New collection", all_access: true
|
||||
Collection.create! name: "New collection", all_access: true
|
||||
end
|
||||
assert_equal accounts("37s").users, collection.users
|
||||
assert_equal User.all, collection.users
|
||||
end
|
||||
|
||||
test "grants access to everyone after update" do
|
||||
collection = Current.set(session: sessions(:david)) do
|
||||
accounts("37s").collections.create! name: "New collection"
|
||||
Collection.create! name: "New collection"
|
||||
end
|
||||
assert_equal [ users(:david) ], collection.users
|
||||
|
||||
collection.update! all_access: true
|
||||
assert_equal accounts("37s").users, collection.users.reload
|
||||
assert_equal User.all, collection.users.reload
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@ require "test_helper"
|
||||
class FilterTest < ActiveSupport::TestCase
|
||||
test "cards" do
|
||||
Current.set session: sessions(:david) do
|
||||
@new_collection = accounts("37s").collections.create! name: "Inaccessible Collection"
|
||||
@new_collection = Collection.create! name: "Inaccessible Collection"
|
||||
@new_card = @new_collection.cards.create!
|
||||
@new_card.update!(stage: workflow_stages(:qa_triage))
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ class NotifierTest < ActiveSupport::TestCase
|
||||
|
||||
test "generate does not create notifications if the event was system-generated" do
|
||||
cards(:logo).drafted!
|
||||
events(:logo_published).update!(creator: accounts("37s").users.system)
|
||||
events(:logo_published).update!(creator: User.system)
|
||||
|
||||
assert_no_difference -> { Notification.count } do
|
||||
Notifier.for(events(:logo_published)).generate
|
||||
|
||||
+1
-15
@@ -1,21 +1,7 @@
|
||||
require "test_helper"
|
||||
|
||||
class TagTest < ActiveSupport::TestCase
|
||||
setup do
|
||||
@account = accounts("37s")
|
||||
end
|
||||
|
||||
test "creating or deleting a tag touches the account, so tags dialog fragment cache is invalidated" do
|
||||
assert_changes -> { @account.reload.updated_at } do
|
||||
@account.tags.create!(title: "ReleaseBlocker")
|
||||
end
|
||||
|
||||
assert_changes -> { @account.reload.updated_at } do
|
||||
@account.tags.find_by(title: "ReleaseBlocker").destroy
|
||||
end
|
||||
end
|
||||
|
||||
test "downcase title" do
|
||||
assert_equal "a tag", @account.tags.create!(title: "A TAG").title
|
||||
assert_equal "a tag", Tag.create!(title: "A TAG").title
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,19 +3,16 @@ require "test_helper"
|
||||
class UserTest < ActiveSupport::TestCase
|
||||
test "create" do
|
||||
user = User.create! \
|
||||
account: accounts("37s"),
|
||||
role: "member",
|
||||
name: "Victor Cooper",
|
||||
email_address: "victor@hey.com",
|
||||
password: "secret123456"
|
||||
|
||||
assert_equal accounts("37s"), user.account
|
||||
assert_equal user, User.authenticate_by(email_address: "victor@hey.com", password: "secret123456")
|
||||
end
|
||||
|
||||
test "creation gives access to all_access collections" do
|
||||
user = User.create! \
|
||||
account: accounts("37s"),
|
||||
role: "member",
|
||||
name: "Victor Cooper",
|
||||
email_address: "victor@hey.com",
|
||||
@@ -37,7 +34,7 @@ class UserTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test "system user" do
|
||||
system_user = accounts("37s").users.system
|
||||
system_user = User.system
|
||||
|
||||
assert system_user.system?
|
||||
assert_equal "System", system_user.name
|
||||
|
||||
Reference in New Issue
Block a user