Phases 0–18: core meetings, webinar, breakouts, team chat, live streaming, town hall, billing, and Ladill Mail calendar wiring. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ActionItem extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_action_items';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'ai_summary_id', 'assignee_ref', 'assignee_name',
|
||||
'description', 'due_date', 'status',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['due_date' => 'date'];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (ActionItem $item) {
|
||||
if (empty($item->uuid)) {
|
||||
$item->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function aiSummary(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(AiSummary::class, 'ai_summary_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class AiSummary extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_ai_summaries';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'session_id', 'transcript_id', 'status',
|
||||
'summary', 'decisions',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['decisions' => 'array'];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (AiSummary $summary) {
|
||||
if (empty($summary->uuid)) {
|
||||
$summary->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function session(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Session::class, 'session_id');
|
||||
}
|
||||
|
||||
public function transcript(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Transcript::class, 'transcript_id');
|
||||
}
|
||||
|
||||
public function actionItems(): HasMany
|
||||
{
|
||||
return $this->hasMany(ActionItem::class, 'ai_summary_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class AuditLog extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_audit_logs';
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'organization_id', 'actor_ref', 'action',
|
||||
'subject_type', 'subject_id', 'metadata', 'ip_address', 'created_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'metadata' => 'array',
|
||||
'created_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public static function record(
|
||||
string $ownerRef,
|
||||
string $action,
|
||||
?int $organizationId = null,
|
||||
?string $actorRef = null,
|
||||
?string $subjectType = null,
|
||||
?int $subjectId = null,
|
||||
?array $metadata = null,
|
||||
): self {
|
||||
return static::create([
|
||||
'owner_ref' => $ownerRef,
|
||||
'organization_id' => $organizationId,
|
||||
'actor_ref' => $actorRef,
|
||||
'action' => $action,
|
||||
'subject_type' => $subjectType,
|
||||
'subject_id' => $subjectId,
|
||||
'metadata' => $metadata,
|
||||
'ip_address' => request()?->ip(),
|
||||
'created_at' => now(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Branch extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'meet_branches';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'organization_id', 'name', 'code', 'address', 'phone', 'is_active',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['is_active' => 'boolean'];
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class BreakoutAssignment extends Model
|
||||
{
|
||||
protected $table = 'meet_breakout_assignments';
|
||||
|
||||
protected $fillable = ['breakout_room_id', 'participant_id'];
|
||||
|
||||
public function breakoutRoom(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(BreakoutRoom::class, 'breakout_room_id');
|
||||
}
|
||||
|
||||
public function participant(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Participant::class, 'participant_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class BreakoutRoom extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_breakout_rooms';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'session_id', 'name', 'media_room_name', 'status', 'closes_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['closes_at' => 'datetime'];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (BreakoutRoom $room) {
|
||||
if (empty($room->uuid)) {
|
||||
$room->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function session(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Session::class, 'session_id');
|
||||
}
|
||||
|
||||
public function assignments(): HasMany
|
||||
{
|
||||
return $this->hasMany(BreakoutAssignment::class, 'breakout_room_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class CalendarConnection extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_calendar_connections';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'user_ref', 'provider',
|
||||
'access_token', 'refresh_token', 'expires_at', 'calendar_id', 'metadata',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'expires_at' => 'datetime',
|
||||
'metadata' => 'array',
|
||||
'access_token' => 'encrypted',
|
||||
'refresh_token' => 'encrypted',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (CalendarConnection $connection) {
|
||||
if (empty($connection->uuid)) {
|
||||
$connection->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function isExpired(): bool
|
||||
{
|
||||
return $this->expires_at !== null && $this->expires_at->isPast();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Channel extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_channels';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'branch_id', 'name', 'slug', 'visibility', 'description',
|
||||
];
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (Channel $channel) {
|
||||
if (empty($channel->uuid)) {
|
||||
$channel->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function members(): HasMany
|
||||
{
|
||||
return $this->hasMany(ChannelMember::class, 'channel_id');
|
||||
}
|
||||
|
||||
public function messages(): HasMany
|
||||
{
|
||||
return $this->hasMany(ChannelMessage::class, 'channel_id');
|
||||
}
|
||||
|
||||
public function isPrivate(): bool
|
||||
{
|
||||
return $this->visibility === 'private';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class ChannelMember extends Model
|
||||
{
|
||||
protected $table = 'meet_channel_members';
|
||||
|
||||
protected $fillable = ['channel_id', 'user_ref', 'role'];
|
||||
|
||||
public function channel(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Channel::class, 'channel_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ChannelMessage extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_channel_messages';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'channel_id', 'sender_ref', 'sender_name', 'body', 'parent_id', 'metadata',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['metadata' => 'array'];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (ChannelMessage $message) {
|
||||
if (empty($message->uuid)) {
|
||||
$message->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function channel(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Channel::class, 'channel_id');
|
||||
}
|
||||
|
||||
public function parent(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ChannelMessage::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function replies(): HasMany
|
||||
{
|
||||
return $this->hasMany(ChannelMessage::class, 'parent_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Concerns;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
trait BelongsToOwner
|
||||
{
|
||||
public function scopeOwned(Builder $query, string $ownerRef): Builder
|
||||
{
|
||||
return $query->where($this->getTable().'.owner_ref', $ownerRef);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ContactGroup extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_contact_groups';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'name', 'description',
|
||||
];
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (ContactGroup $group) {
|
||||
if (empty($group->uuid)) {
|
||||
$group->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function members(): HasMany
|
||||
{
|
||||
return $this->hasMany(ContactGroupMember::class, 'contact_group_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class ContactGroupMember extends Model
|
||||
{
|
||||
protected $table = 'meet_contact_group_members';
|
||||
|
||||
protected $fillable = [
|
||||
'contact_group_id', 'email', 'user_ref', 'display_name',
|
||||
];
|
||||
|
||||
public function group(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ContactGroup::class, 'contact_group_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class DirectConversation extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_direct_conversations';
|
||||
|
||||
protected $fillable = ['uuid', 'owner_ref', 'organization_id', 'type', 'title'];
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (DirectConversation $conversation) {
|
||||
if (empty($conversation->uuid)) {
|
||||
$conversation->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function participants(): HasMany
|
||||
{
|
||||
return $this->hasMany(DirectParticipant::class, 'conversation_id');
|
||||
}
|
||||
|
||||
public function messages(): HasMany
|
||||
{
|
||||
return $this->hasMany(DirectMessage::class, 'conversation_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class DirectMessage extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_direct_messages';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'conversation_id', 'sender_ref', 'sender_name', 'body', 'parent_id',
|
||||
];
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (DirectMessage $message) {
|
||||
if (empty($message->uuid)) {
|
||||
$message->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function conversation(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(DirectConversation::class, 'conversation_id');
|
||||
}
|
||||
|
||||
public function parent(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(DirectMessage::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function replies(): HasMany
|
||||
{
|
||||
return $this->hasMany(DirectMessage::class, 'parent_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class DirectParticipant extends Model
|
||||
{
|
||||
protected $table = 'meet_direct_participants';
|
||||
|
||||
protected $fillable = ['conversation_id', 'user_ref'];
|
||||
|
||||
public function conversation(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(DirectConversation::class, 'conversation_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class FileDownload extends Model
|
||||
{
|
||||
public $timestamps = false;
|
||||
|
||||
protected $table = 'meet_file_downloads';
|
||||
|
||||
protected $fillable = [
|
||||
'session_file_id', 'downloaded_by_ref', 'downloaded_by_name', 'ip_address', 'downloaded_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['downloaded_at' => 'datetime'];
|
||||
}
|
||||
|
||||
public function file(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(SessionFile::class, 'session_file_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Invitation extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_invitations';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'room_id', 'email', 'user_ref',
|
||||
'display_name', 'role', 'status', 'rsvp_token', 'responded_at',
|
||||
'calendar_event_id', 'sent_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'sent_at' => 'datetime',
|
||||
'responded_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (Invitation $invitation) {
|
||||
if (empty($invitation->uuid)) {
|
||||
$invitation->uuid = (string) Str::uuid();
|
||||
}
|
||||
if (empty($invitation->rsvp_token)) {
|
||||
$invitation->rsvp_token = Str::random(40);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function rsvpUrl(): string
|
||||
{
|
||||
return route('meet.invitations.rsvp', ['invitation' => $this->uuid, 'token' => $this->rsvp_token]);
|
||||
}
|
||||
|
||||
public function room(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Room::class, 'room_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class LiveStream extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_live_streams';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'session_id', 'platform', 'rtmp_url', 'stream_key',
|
||||
'status', 'layout', 'health', 'started_at', 'ended_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'started_at' => 'datetime',
|
||||
'ended_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (LiveStream $stream) {
|
||||
if (empty($stream->uuid)) {
|
||||
$stream->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function session(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Session::class, 'session_id');
|
||||
}
|
||||
|
||||
public function setStreamKeyAttribute(?string $value): void
|
||||
{
|
||||
$this->attributes['stream_key'] = $value ? Crypt::encryptString($value) : null;
|
||||
}
|
||||
|
||||
public function getStreamKeyAttribute(?string $value): ?string
|
||||
{
|
||||
if (! $value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return Crypt::decryptString($value);
|
||||
} catch (\Throwable) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class MeetPoll extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_polls';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'session_id', 'question', 'options', 'status',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['options' => 'array'];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (MeetPoll $poll) {
|
||||
if (empty($poll->uuid)) {
|
||||
$poll->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function session(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Session::class, 'session_id');
|
||||
}
|
||||
|
||||
public function votes(): HasMany
|
||||
{
|
||||
return $this->hasMany(PollVote::class, 'poll_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Member extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_members';
|
||||
|
||||
protected $fillable = ['owner_ref', 'organization_id', 'user_ref', 'role', 'branch_id'];
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
|
||||
public function hasRole(string ...$roles): bool
|
||||
{
|
||||
return in_array($this->role, $roles, true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Message extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_messages';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'session_id', 'breakout_room_id', 'sender_ref', 'sender_name',
|
||||
'type', 'recipient_ref', 'body', 'metadata',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['metadata' => 'array'];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (Message $message) {
|
||||
if (empty($message->uuid)) {
|
||||
$message->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function session(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Session::class, 'session_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Organization extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'meet_organizations';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'name', 'slug', 'logo_path', 'timezone', 'license_tier', 'usage_quotas',
|
||||
'settings', 'security_policy',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'settings' => 'array',
|
||||
'security_policy' => 'array',
|
||||
'usage_quotas' => 'array',
|
||||
];
|
||||
}
|
||||
|
||||
public function branches(): HasMany
|
||||
{
|
||||
return $this->hasMany(Branch::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function members(): HasMany
|
||||
{
|
||||
return $this->hasMany(Member::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function templates(): HasMany
|
||||
{
|
||||
return $this->hasMany(Template::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function securitySetting(string $key, mixed $default = null): mixed
|
||||
{
|
||||
return data_get($this->security_policy, $key, data_get(config('meet.security_defaults'), $key, $default));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Participant extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_participants';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'session_id', 'user_ref', 'display_name', 'email',
|
||||
'role', 'status', 'joined_at', 'left_at', 'device_info', 'ip_address',
|
||||
'hand_raised', 'is_muted', 'is_video_off', 'breakout_room_id',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'joined_at' => 'datetime',
|
||||
'left_at' => 'datetime',
|
||||
'hand_raised' => 'boolean',
|
||||
'is_muted' => 'boolean',
|
||||
'is_video_off' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (Participant $participant) {
|
||||
if (empty($participant->uuid)) {
|
||||
$participant->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function session(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Session::class, 'session_id');
|
||||
}
|
||||
|
||||
public function isHost(): bool
|
||||
{
|
||||
return in_array($this->role, ['host', 'co_host'], true);
|
||||
}
|
||||
|
||||
public function isPanelist(): bool
|
||||
{
|
||||
return $this->role === 'panelist';
|
||||
}
|
||||
|
||||
public function isAttendee(): bool
|
||||
{
|
||||
return $this->role === 'attendee';
|
||||
}
|
||||
|
||||
public function canPublishMedia(): bool
|
||||
{
|
||||
return $this->role !== 'attendee';
|
||||
}
|
||||
|
||||
public function breakoutRoom(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(BreakoutRoom::class, 'breakout_room_id');
|
||||
}
|
||||
|
||||
public function isJoined(): bool
|
||||
{
|
||||
return $this->status === 'joined';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class PollVote extends Model
|
||||
{
|
||||
protected $table = 'meet_poll_votes';
|
||||
|
||||
protected $fillable = ['poll_id', 'participant_uuid', 'option_index'];
|
||||
|
||||
public function poll(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(MeetPoll::class, 'poll_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class QaQuestion extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_qa_questions';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'session_id', 'participant_uuid', 'asker_name',
|
||||
'question', 'status', 'answer', 'answered_by', 'upvotes',
|
||||
];
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (QaQuestion $q) {
|
||||
if (empty($q->uuid)) {
|
||||
$q->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function session(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Session::class, 'session_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Reaction extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_reactions';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'session_id', 'participant_ref', 'sender_name', 'emoji',
|
||||
];
|
||||
|
||||
public function session(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Session::class, 'session_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Recording extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_recordings';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'session_id', 'status', 'layout', 'storage_path',
|
||||
'thumbnail_path', 'file_size', 'duration_seconds', 'started_by_ref',
|
||||
'started_at', 'ended_at', 'failure_reason', 'metadata',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'started_at' => 'datetime',
|
||||
'ended_at' => 'datetime',
|
||||
'metadata' => 'array',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (Recording $recording) {
|
||||
if (empty($recording->uuid)) {
|
||||
$recording->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function session(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Session::class, 'session_id');
|
||||
}
|
||||
|
||||
public function isReady(): bool
|
||||
{
|
||||
return $this->status === 'ready';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Room extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'meet_rooms';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'branch_id', 'host_user_ref',
|
||||
'title', 'description', 'type', 'status', 'slug', 'scheduled_at',
|
||||
'duration_minutes', 'timezone', 'passcode', 'settings', 'source', 'calendar_event_id',
|
||||
'template_id', 'recurring_series_id', 'recurrence_rule', 'recurrence_interval', 'recurrence_until',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'scheduled_at' => 'datetime',
|
||||
'recurrence_until' => 'date',
|
||||
'settings' => 'array',
|
||||
'source' => 'array',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (Room $room) {
|
||||
if (empty($room->uuid)) {
|
||||
$room->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
|
||||
public function sessions(): HasMany
|
||||
{
|
||||
return $this->hasMany(Session::class, 'room_id');
|
||||
}
|
||||
|
||||
public function invitations(): HasMany
|
||||
{
|
||||
return $this->hasMany(Invitation::class, 'room_id');
|
||||
}
|
||||
|
||||
public function webinarRegistrations(): HasMany
|
||||
{
|
||||
return $this->hasMany(WebinarRegistration::class, 'room_id');
|
||||
}
|
||||
|
||||
public function sessionFiles(): HasMany
|
||||
{
|
||||
return $this->hasMany(SessionFile::class, 'room_id');
|
||||
}
|
||||
|
||||
public function isWebinar(): bool
|
||||
{
|
||||
return $this->type === 'webinar';
|
||||
}
|
||||
|
||||
public function isTownHall(): bool
|
||||
{
|
||||
return $this->type === 'town_hall';
|
||||
}
|
||||
|
||||
public function template(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Template::class, 'template_id');
|
||||
}
|
||||
|
||||
public function isRecurring(): bool
|
||||
{
|
||||
return filled($this->recurrence_rule);
|
||||
}
|
||||
|
||||
public function activeSession(): ?Session
|
||||
{
|
||||
return $this->sessions()->where('status', 'live')->latest()->first();
|
||||
}
|
||||
|
||||
public function setting(string $key, mixed $default = null): mixed
|
||||
{
|
||||
return data_get($this->settings, $key, data_get(config('meet.default_settings'), $key, $default));
|
||||
}
|
||||
|
||||
public function isLive(): bool
|
||||
{
|
||||
return $this->status === 'live';
|
||||
}
|
||||
|
||||
public function joinUrl(): string
|
||||
{
|
||||
return url('/r/'.$this->uuid);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Session extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_sessions';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'room_id', 'parent_session_id', 'media_room_name', 'status',
|
||||
'session_mode', 'presenter_refs', 'is_breakout', 'started_at', 'ended_at',
|
||||
'peak_participants', 'is_locked', 'locked_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'started_at' => 'datetime',
|
||||
'ended_at' => 'datetime',
|
||||
'locked_at' => 'datetime',
|
||||
'is_locked' => 'boolean',
|
||||
'is_breakout' => 'boolean',
|
||||
'presenter_refs' => 'array',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (Session $session) {
|
||||
if (empty($session->uuid)) {
|
||||
$session->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function room(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Room::class, 'room_id');
|
||||
}
|
||||
|
||||
public function participants(): HasMany
|
||||
{
|
||||
return $this->hasMany(Participant::class, 'session_id');
|
||||
}
|
||||
|
||||
public function messages(): HasMany
|
||||
{
|
||||
return $this->hasMany(Message::class, 'session_id');
|
||||
}
|
||||
|
||||
public function reactions(): HasMany
|
||||
{
|
||||
return $this->hasMany(Reaction::class, 'session_id');
|
||||
}
|
||||
|
||||
public function recordings(): HasMany
|
||||
{
|
||||
return $this->hasMany(Recording::class, 'session_id');
|
||||
}
|
||||
|
||||
public function transcripts(): HasMany
|
||||
{
|
||||
return $this->hasMany(Transcript::class, 'session_id');
|
||||
}
|
||||
|
||||
public function aiSummaries(): HasMany
|
||||
{
|
||||
return $this->hasMany(AiSummary::class, 'session_id');
|
||||
}
|
||||
|
||||
public function qaQuestions(): HasMany
|
||||
{
|
||||
return $this->hasMany(QaQuestion::class, 'session_id');
|
||||
}
|
||||
|
||||
public function polls(): HasMany
|
||||
{
|
||||
return $this->hasMany(MeetPoll::class, 'session_id');
|
||||
}
|
||||
|
||||
public function breakoutRooms(): HasMany
|
||||
{
|
||||
return $this->hasMany(BreakoutRoom::class, 'session_id');
|
||||
}
|
||||
|
||||
public function whiteboard(): \Illuminate\Database\Eloquent\Relations\HasOne
|
||||
{
|
||||
return $this->hasOne(Whiteboard::class, 'session_id');
|
||||
}
|
||||
|
||||
public function sessionFiles(): HasMany
|
||||
{
|
||||
return $this->hasMany(SessionFile::class, 'session_id');
|
||||
}
|
||||
|
||||
public function liveStreams(): HasMany
|
||||
{
|
||||
return $this->hasMany(LiveStream::class, 'session_id');
|
||||
}
|
||||
|
||||
public function activeParticipants(): HasMany
|
||||
{
|
||||
return $this->participants()->where('status', 'joined');
|
||||
}
|
||||
|
||||
public function isLive(): bool
|
||||
{
|
||||
return $this->status === 'live';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class SessionFile extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_session_files';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'room_id', 'session_id', 'uploaded_by_ref', 'uploaded_by_name',
|
||||
'original_name', 'storage_path', 'mime_type', 'file_size', 'drive_file_id', 'expires_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['expires_at' => 'datetime'];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (SessionFile $file) {
|
||||
if (empty($file->uuid)) {
|
||||
$file->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function room(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Room::class, 'room_id');
|
||||
}
|
||||
|
||||
public function session(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Session::class, 'session_id');
|
||||
}
|
||||
|
||||
public function downloads(): HasMany
|
||||
{
|
||||
return $this->hasMany(FileDownload::class, 'session_file_id');
|
||||
}
|
||||
|
||||
public function isExpired(): bool
|
||||
{
|
||||
return $this->expires_at !== null && $this->expires_at->isPast();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Template extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'meet_templates';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'name', 'description',
|
||||
'duration_minutes', 'settings', 'is_default',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['settings' => 'array', 'is_default' => 'boolean'];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (Template $template) {
|
||||
if (empty($template->uuid)) {
|
||||
$template->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function mergedSettings(): array
|
||||
{
|
||||
return array_merge(config('meet.default_settings'), $this->settings ?? []);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Transcript extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_transcripts';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'session_id', 'recording_id', 'status',
|
||||
'content', 'segments', 'live_captions_enabled',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['segments' => 'array', 'live_captions_enabled' => 'boolean'];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (Transcript $transcript) {
|
||||
if (empty($transcript->uuid)) {
|
||||
$transcript->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function session(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Session::class, 'session_id');
|
||||
}
|
||||
|
||||
public function recording(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Recording::class, 'recording_id');
|
||||
}
|
||||
|
||||
public function aiSummary(): HasOne
|
||||
{
|
||||
return $this->hasOne(AiSummary::class, 'transcript_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class UsageRecord extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_usage_records';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'organization_id', 'branch_id', 'metric', 'quantity', 'metadata', 'recorded_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'metadata' => 'array',
|
||||
'recorded_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
/**
|
||||
* Thin local mirror of the platform identity (auth.ladill.com owns users).
|
||||
* Keyed by the OIDC `sub` (public_id); every Care record is scoped to it.
|
||||
*/
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasApiTokens, Notifiable;
|
||||
|
||||
protected $fillable = ['public_id', 'name', 'email', 'avatar_url', 'password', 'last_app_active_at'];
|
||||
|
||||
protected $hidden = ['password', 'remember_token'];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'last_app_active_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
];
|
||||
}
|
||||
|
||||
public function ownerRef(): string
|
||||
{
|
||||
return (string) $this->public_id;
|
||||
}
|
||||
|
||||
public function avatarUrl(): ?string
|
||||
{
|
||||
$url = trim((string) $this->avatar_url);
|
||||
|
||||
return $url !== '' ? $url : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class WebhookEndpoint extends Model
|
||||
{
|
||||
protected $table = 'meet_webhook_endpoints';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'url', 'secret', 'events', 'is_active',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'events' => 'array',
|
||||
'is_active' => 'boolean',
|
||||
'secret' => 'encrypted',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (WebhookEndpoint $endpoint) {
|
||||
if (empty($endpoint->uuid)) {
|
||||
$endpoint->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function subscribesTo(string $event): bool
|
||||
{
|
||||
$events = $this->events ?? config('meet.webhook_events', []);
|
||||
|
||||
return in_array('*', $events, true) || in_array($event, $events, true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class WebinarRegistration extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_webinar_registrations';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'room_id', 'email', 'display_name', 'status',
|
||||
'access_token', 'approved_at', 'metadata',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['approved_at' => 'datetime', 'metadata' => 'array'];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (WebinarRegistration $reg) {
|
||||
if (empty($reg->uuid)) {
|
||||
$reg->uuid = (string) Str::uuid();
|
||||
}
|
||||
if (empty($reg->access_token)) {
|
||||
$reg->access_token = Str::random(48);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function room(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Room::class, 'room_id');
|
||||
}
|
||||
|
||||
public function isApproved(): bool
|
||||
{
|
||||
return $this->status === 'approved';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Whiteboard extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'meet_whiteboards';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'room_id', 'session_id', 'template', 'state',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['state' => 'array'];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (Whiteboard $board) {
|
||||
if (empty($board->uuid)) {
|
||||
$board->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function room(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Room::class, 'room_id');
|
||||
}
|
||||
|
||||
public function session(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Session::class, 'session_id');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user