Files
numolus/app/models/user.rb
T
wkhandClaude Opus 5.5 e14bada114 Add Rails backend: accounts via magic link, server documents, sharing
The app becomes a Rails 8 application; the Vue frontend moves to
app/frontend and is served through vite_rails.

- Without an account documents stay in the browser (IndexedDB). Sign-in
  is by magic link or the 6-digit code from the same mail; afterwards
  local documents can be uploaded into the account.
- Server documents (/d/<id>) with versioned saves and a single-editor
  lock per browser tab; others see them read-only and follow by polling.
- Sharing via link (works without an account) and via e-mail invitation,
  roles viewer/editor; the owner manages links and people.
- Store gains a read-only mode that blocks all content changes.
- Solid Queue, Cache and Cable share the one PostgreSQL database.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 20:09:06 +02:00

29 lines
1.0 KiB
Ruby

class User < ApplicationRecord
COLORS = %w[#e67e22 #2980b9 #27ae60 #8e44ad #c0392b #16a085 #d35400 #2c3e50].freeze
has_many :sessions, dependent: :destroy
has_many :owned_documents, class_name: "Document", foreign_key: :owner_id, dependent: :destroy, inverse_of: :owner
has_many :document_memberships, dependent: :destroy
has_many :shared_documents, through: :document_memberships, source: :document
normalizes :email, with: ->(e) { e.strip.downcase }
validates :email, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
validates :display_name, length: { maximum: 80 }
before_create { self.color ||= COLORS.sample }
# Name shown to others (share dialog, lock holder, later: cursors).
def name
display_name.presence || email.split("@").first
end
# Documents this user owns or has been given access to.
def accessible_documents
Document.where(owner_id: id).or(Document.where(id: document_memberships.select(:document_id)))
end
def as_json(*)
{ id:, email:, name:, display_name:, color: }
end
end