PHP Rebuild
CI / ci (push) Canceled after 0s

Initial PHP rebuild of the app
This commit is contained in:
Stefan Lazic committed 2026-09-05 08:21:33 +01:00
1 parent 8a2b211069
commit 2ef3654841
690 files changed
+33944 -12046

No files matched your search

+16
View File
@@ -0,0 +1,16 @@
<?php
namespace App\Models;
use App\Enums\InstallationStatus;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
class ApplicationInstallation extends Model
{
use UsesStringIds;
public const CREATED_AT = 'createdAt'; public const UPDATED_AT = 'updatedAt';
protected $table = 'ApplicationInstallation';
protected $fillable = ['id', 'status', 'installedAt', 'installedVersion', 'initialAdminUserId', 'primaryBusinessId', 'metadata', 'failureReason'];
protected function casts(): array { return ['status' => InstallationStatus::class, 'installedAt' => 'datetime', 'metadata' => 'array']; }
}
+32
View File
@@ -0,0 +1,32 @@
<?php
namespace App\Models;
use App\Enums\AppointmentStatus;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Appointment extends Model
{
use UsesStringIds;
public const CREATED_AT = 'createdAt';
public const UPDATED_AT = 'updatedAt';
protected $table = 'Appointment';
protected $fillable = ['businessId', 'customerId', 'staffId', 'status', 'startAt', 'endAt', 'notes', 'discountAmount', 'cancellationReason', 'cancelledAt', 'cancelledByUserId', 'createdByUserId'];
protected function casts(): array { return ['status' => AppointmentStatus::class, 'startAt' => 'datetime', 'endAt' => 'datetime', 'cancelledAt' => 'datetime', 'discountAmount' => 'decimal:2']; }
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
public function customer(): BelongsTo { return $this->belongsTo(CustomerProfile::class, 'customerId'); }
public function staff(): BelongsTo { return $this->belongsTo(StaffProfile::class, 'staffId'); }
public function services(): HasMany { return $this->hasMany(AppointmentService::class, 'appointmentId'); }
public function guestAccessToken(): HasOne { return $this->hasOne(GuestAppointmentAccessToken::class, 'appointmentId'); }
public function calendarEvents(): HasMany { return $this->hasMany(AppointmentCalendarEvent::class, 'appointmentId'); }
public function loyaltyTransactions(): HasMany { return $this->hasMany(LoyaltyTransaction::class, 'appointmentId'); }
public function notifications(): HasMany { return $this->hasMany(Notification::class, 'appointmentId'); }
public function appliedLoyaltyRewards(): HasMany { return $this->hasMany(LoyaltyReward::class, 'appliedToAppointmentId'); }
public function cancelledByUser(): BelongsTo { return $this->belongsTo(User::class, 'cancelledByUserId'); }
public function createdByUser(): BelongsTo { return $this->belongsTo(User::class, 'createdByUserId'); }
}
+19
View File
@@ -0,0 +1,19 @@
<?php
namespace App\Models;
use App\Enums\CalendarSyncStatus;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class AppointmentCalendarEvent extends Model
{
use UsesStringIds;
public const CREATED_AT = 'createdAt'; public const UPDATED_AT = 'updatedAt';
protected $table = 'AppointmentCalendarEvent';
protected $fillable = ['appointmentId', 'connectionId', 'providerEventId', 'providerCalendarId', 'status', 'lastSyncedAt', 'lastSyncError', 'sourceVersion'];
protected function casts(): array { return ['status' => CalendarSyncStatus::class, 'lastSyncedAt' => 'datetime']; }
public function appointment(): BelongsTo { return $this->belongsTo(Appointment::class, 'appointmentId'); }
public function connection(): BelongsTo { return $this->belongsTo(StaffCalendarConnection::class, 'connectionId'); }
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class AppointmentService extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'AppointmentService';
protected $fillable = ['appointmentId', 'serviceId', 'priceAtBooking', 'durationAtBookingMinutes'];
protected function casts(): array { return ['priceAtBooking' => 'decimal:2']; }
public function appointment(): BelongsTo { return $this->belongsTo(Appointment::class, 'appointmentId'); }
public function service(): BelongsTo { return $this->belongsTo(Service::class, 'serviceId'); }
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class AuditLog extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'AuditLog';
protected $fillable = ['businessId', 'actorUserId', 'action', 'entityType', 'entityId', 'metadata'];
protected function casts(): array { return ['metadata' => 'array']; }
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
public function actorUser(): BelongsTo { return $this->belongsTo(User::class, 'actorUserId'); }
}
+17
View File
@@ -0,0 +1,17 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class BookingRule extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'BookingRule';
protected $fillable = ['businessId', 'minNoticeMinutes', 'maxAdvanceDays', 'cancellationWindowHours', 'rescheduleWindowHours', 'slotIntervalMinutes', 'bufferBeforeMinutes', 'bufferAfterMinutes', 'maxAppointmentsPerDay', 'maxAppointmentsPerStaffPerDay', 'customerCanChooseStaff', 'allowGuestBooking', 'requireApproval', 'requireDeposit'];
protected function casts(): array { return ['customerCanChooseStaff' => 'boolean', 'allowGuestBooking' => 'boolean', 'requireApproval' => 'boolean', 'requireDeposit' => 'boolean']; }
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
}
+16
View File
@@ -0,0 +1,16 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class BreakDay extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'BreakDay';
protected $fillable = ['breakId', 'dayOfWeek'];
public function break(): BelongsTo { return $this->belongsTo(StaffBreak::class, 'breakId'); }
}
+49
View File
@@ -0,0 +1,49 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
class Business extends Model
{
use UsesStringIds;
public const CREATED_AT = 'createdAt';
public const UPDATED_AT = 'updatedAt';
protected $table = 'Business';
protected $fillable = [
'slug', 'name', 'shortName', 'description', 'logoUrl', 'coverImageUrl',
'faviconUrl', 'appIconUrl', 'themeColor', 'backgroundColor', 'phone',
'email', 'website', 'instagramUrl', 'facebookUrl', 'timezone', 'currency',
'locale', 'bottomNavShowLabels', 'icon192Url', 'icon512Url', 'maskableIcon192Url',
'maskableIcon512Url', 'splashScreens', 'welcomeBackgroundDesktopUrl',
'welcomeBackgroundMobileUrl', 'googlePlaceId', 'googleRating', 'googleRatingCount',
];
protected function casts(): array
{
return ['bottomNavShowLabels' => 'boolean', 'splashScreens' => 'array', 'googleRating' => 'decimal:1'];
}
public function domains(): HasMany { return $this->hasMany(BusinessDomain::class, 'businessId'); }
public function locations(): HasMany { return $this->hasMany(BusinessLocation::class, 'businessId'); }
public function hours(): HasMany { return $this->hasMany(BusinessHours::class, 'businessId'); }
public function settings(): HasOne { return $this->hasOne(BusinessSettings::class, 'businessId'); }
public function bookingRule(): HasOne { return $this->hasOne(BookingRule::class, 'businessId'); }
public function staff(): HasMany { return $this->hasMany(StaffProfile::class, 'businessId'); }
public function serviceCategories(): HasMany { return $this->hasMany(ServiceCategory::class, 'businessId'); }
public function services(): HasMany { return $this->hasMany(Service::class, 'businessId'); }
public function appointments(): HasMany { return $this->hasMany(Appointment::class, 'businessId'); }
public function loyaltyProgramme(): HasOne { return $this->hasOne(LoyaltyProgramme::class, 'businessId'); }
public function staffInvitations(): HasMany { return $this->hasMany(StaffInvitation::class, 'businessId'); }
public function notifications(): HasMany { return $this->hasMany(Notification::class, 'businessId'); }
public function pushSubscriptions(): HasMany { return $this->hasMany(PushSubscription::class, 'businessId'); }
public function mediaAssets(): HasMany { return $this->hasMany(MediaAsset::class, 'businessId'); }
public function galleryImages(): HasMany { return $this->hasMany(BusinessGalleryImage::class, 'businessId'); }
public function reviews(): HasMany { return $this->hasMany(Review::class, 'businessId'); }
}
+26
View File
@@ -0,0 +1,26 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class BusinessDomain extends Model
{
use UsesStringIds;
public const CREATED_AT = 'createdAt';
public const UPDATED_AT = 'updatedAt';
protected $table = 'business_domains';
protected $fillable = ['businessId', 'hostname', 'isPrimary', 'isActive'];
protected function casts(): array
{
return ['isPrimary' => 'boolean', 'isActive' => 'boolean'];
}
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
}
+19
View File
@@ -0,0 +1,19 @@
<?php
namespace App\Models;
use App\Enums\GalleryPlacement;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class BusinessGalleryImage extends Model
{
use UsesStringIds;
public const CREATED_AT = 'createdAt'; public const UPDATED_AT = 'updatedAt';
protected $table = 'BusinessGalleryImage';
protected $fillable = ['businessId', 'placement', 'mediaAssetId', 'imageUrl', 'category', 'caption', 'displayOrder', 'isActive'];
protected function casts(): array { return ['placement' => GalleryPlacement::class, 'isActive' => 'boolean']; }
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
public function mediaAsset(): BelongsTo { return $this->belongsTo(MediaAsset::class, 'mediaAssetId'); }
}
+17
View File
@@ -0,0 +1,17 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class BusinessHours extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'BusinessHours';
protected $fillable = ['businessId', 'dayOfWeek', 'isClosed', 'opensAtMinutes', 'closesAtMinutes'];
protected function casts(): array { return ['isClosed' => 'boolean']; }
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
}
+21
View File
@@ -0,0 +1,21 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class BusinessLocation extends Model
{
use UsesStringIds;
public const CREATED_AT = 'createdAt';
public const UPDATED_AT = 'updatedAt';
protected $table = 'BusinessLocation';
protected $fillable = ['businessId', 'name', 'addressLine1', 'addressLine2', 'city', 'region', 'postalCode', 'country', 'isPrimary'];
protected function casts(): array { return ['isPrimary' => 'boolean']; }
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
}
+17
View File
@@ -0,0 +1,17 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class BusinessSettings extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'BusinessSettings';
protected $fillable = ['businessId', 'cancellationPolicy', 'lateArrivalPolicy', 'bookingTerms', 'privacyPolicyUrl', 'reviewsMinRating', 'reviewsExcludeRatingOnly'];
protected function casts(): array { return ['reviewsExcludeRatingOnly' => 'boolean']; }
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
}
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace App\Models\Concerns;
use Illuminate\Support\Str;
trait UsesStringIds
{
protected static function bootUsesStringIds(): void
{
static::creating(function ($model): void {
if (! $model->getKey()) {
$model->setAttribute($model->getKeyName(), Str::lower(Str::random(25)));
}
});
}
public function getIncrementing(): bool
{
return false;
}
public function getKeyType(): string
{
return 'string';
}
}
+17
View File
@@ -0,0 +1,17 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class CustomerNote extends Model
{
use UsesStringIds;
public const CREATED_AT = 'createdAt'; public const UPDATED_AT = 'updatedAt';
protected $table = 'CustomerNote';
protected $fillable = ['customerId', 'authorStaffId', 'body'];
public function customer(): BelongsTo { return $this->belongsTo(CustomerProfile::class, 'customerId'); }
public function author(): BelongsTo { return $this->belongsTo(StaffProfile::class, 'authorStaffId'); }
}
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class CustomerProfile extends Model
{
use UsesStringIds;
public const CREATED_AT = 'createdAt';
public const UPDATED_AT = 'updatedAt';
protected $table = 'CustomerProfile';
protected $fillable = ['businessId', 'userId', 'firstName', 'lastName', 'email', 'phone', 'isGuest', 'preferredBarberId'];
protected function casts(): array { return ['isGuest' => 'boolean']; }
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
public function user(): BelongsTo { return $this->belongsTo(User::class, 'userId'); }
public function preferredBarber(): BelongsTo { return $this->belongsTo(StaffProfile::class, 'preferredBarberId'); }
public function appointments(): HasMany { return $this->hasMany(Appointment::class, 'customerId'); }
public function loyaltyAccounts(): HasMany { return $this->hasMany(LoyaltyAccount::class, 'customerId'); }
public function notes(): HasMany { return $this->hasMany(CustomerNote::class, 'customerId'); }
public function receivedNotifications(): HasMany { return $this->hasMany(Notification::class, 'recipientCustomerId'); }
public function pushSubscriptions(): HasMany { return $this->hasMany(PushSubscription::class, 'customerId'); }
}
@@ -0,0 +1,17 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class GuestAppointmentAccessToken extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'GuestAppointmentAccessToken';
protected $fillable = ['appointmentId', 'tokenHash', 'expiresAt', 'revokedAt', 'lastUsedAt'];
protected function casts(): array { return ['expiresAt' => 'datetime', 'revokedAt' => 'datetime', 'lastUsedAt' => 'datetime']; }
public function appointment(): BelongsTo { return $this->belongsTo(Appointment::class, 'appointmentId'); }
}
+20
View File
@@ -0,0 +1,20 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class LoyaltyAccount extends Model
{
use UsesStringIds;
public const CREATED_AT = 'createdAt'; public const UPDATED_AT = 'updatedAt';
protected $table = 'LoyaltyAccount';
protected $fillable = ['customerId', 'loyaltyProgrammeId', 'currentStamps'];
public function customer(): BelongsTo { return $this->belongsTo(CustomerProfile::class, 'customerId'); }
public function programme(): BelongsTo { return $this->belongsTo(LoyaltyProgramme::class, 'loyaltyProgrammeId'); }
public function transactions(): HasMany { return $this->hasMany(LoyaltyTransaction::class, 'loyaltyAccountId'); }
public function rewards(): HasMany { return $this->hasMany(LoyaltyReward::class, 'loyaltyAccountId'); }
}
+17
View File
@@ -0,0 +1,17 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class LoyaltyEligibleService extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'LoyaltyEligibleService';
protected $fillable = ['loyaltyProgrammeId', 'serviceId'];
public function programme(): BelongsTo { return $this->belongsTo(LoyaltyProgramme::class, 'loyaltyProgrammeId'); }
public function service(): BelongsTo { return $this->belongsTo(Service::class, 'serviceId'); }
}
+17
View File
@@ -0,0 +1,17 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class LoyaltyEligibleStaff extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'LoyaltyEligibleStaff';
protected $fillable = ['loyaltyProgrammeId', 'staffId'];
public function programme(): BelongsTo { return $this->belongsTo(LoyaltyProgramme::class, 'loyaltyProgrammeId'); }
public function staff(): BelongsTo { return $this->belongsTo(StaffProfile::class, 'staffId'); }
}
+23
View File
@@ -0,0 +1,23 @@
<?php
namespace App\Models;
use App\Enums\{LoyaltyCardFont, LoyaltyCardTextSize, RewardPositionMode, RewardType};
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class LoyaltyProgramme extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'LoyaltyProgramme';
protected $fillable = ['businessId', 'isEnabled', 'stampsRequired', 'rewardPosition', 'rewardType', 'rewardValue', 'rewardLabel', 'maxRewardValue', 'freeServiceId', 'autoApplyReward', 'requiresStaffApproval', 'stampsExpireAfterDays', 'rewardExpiresAfterDays', 'earnOnCancelled', 'earnOnNoShow', 'cardBackgroundColor', 'cardBackgroundImageUrl', 'stampIcon', 'termsLine', 'cardTitleText', 'cardFont', 'cardTitleTextSize', 'cardTitleTextColor', 'cardBorderColor', 'cardMemberNumberColor'];
protected function casts(): array { return ['isEnabled' => 'boolean', 'rewardType' => RewardType::class, 'rewardPosition' => RewardPositionMode::class, 'cardFont' => LoyaltyCardFont::class, 'cardTitleTextSize' => LoyaltyCardTextSize::class, 'rewardValue' => 'decimal:2', 'maxRewardValue' => 'decimal:2', 'autoApplyReward' => 'boolean', 'requiresStaffApproval' => 'boolean', 'earnOnCancelled' => 'boolean', 'earnOnNoShow' => 'boolean']; }
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
public function freeService(): BelongsTo { return $this->belongsTo(Service::class, 'freeServiceId'); }
public function eligibleServices(): HasMany { return $this->hasMany(LoyaltyEligibleService::class, 'loyaltyProgrammeId'); }
public function eligibleStaff(): HasMany { return $this->hasMany(LoyaltyEligibleStaff::class, 'loyaltyProgrammeId'); }
public function accounts(): HasMany { return $this->hasMany(LoyaltyAccount::class, 'loyaltyProgrammeId'); }
}
+22
View File
@@ -0,0 +1,22 @@
<?php
namespace App\Models;
use App\Enums\{RewardStatus, RewardType};
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class LoyaltyReward extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'LoyaltyReward';
protected $fillable = ['loyaltyAccountId', 'rewardType', 'value', 'label', 'status', 'appliedToAppointmentId', 'redeemedAt', 'redeemedByStaffId', 'expiresAt'];
protected function casts(): array { return ['rewardType' => RewardType::class, 'status' => RewardStatus::class, 'value' => 'decimal:2', 'redeemedAt' => 'datetime', 'expiresAt' => 'datetime']; }
public function account(): BelongsTo { return $this->belongsTo(LoyaltyAccount::class, 'loyaltyAccountId'); }
public function appointment(): BelongsTo { return $this->belongsTo(Appointment::class, 'appliedToAppointmentId'); }
public function redeemedByStaff(): BelongsTo { return $this->belongsTo(StaffProfile::class, 'redeemedByStaffId'); }
public function notifications(): HasMany { return $this->hasMany(Notification::class, 'loyaltyRewardId'); }
}
+20
View File
@@ -0,0 +1,20 @@
<?php
namespace App\Models;
use App\Enums\LoyaltyTransactionType;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class LoyaltyTransaction extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'LoyaltyTransaction';
protected $fillable = ['loyaltyAccountId', 'type', 'amount', 'reason', 'appointmentId', 'authoredByStaffId'];
protected function casts(): array { return ['type' => LoyaltyTransactionType::class]; }
public function account(): BelongsTo { return $this->belongsTo(LoyaltyAccount::class, 'loyaltyAccountId'); }
public function appointment(): BelongsTo { return $this->belongsTo(Appointment::class, 'appointmentId'); }
public function authoredByStaff(): BelongsTo { return $this->belongsTo(StaffProfile::class, 'authoredByStaffId'); }
}
+19
View File
@@ -0,0 +1,19 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class MediaAsset extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'MediaAsset';
protected $fillable = ['businessId', 'url', 'originalFilename', 'mimeType', 'sizeBytes', 'width', 'height', 'category', 'uploadedByUserId'];
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
public function uploadedByUser(): BelongsTo { return $this->belongsTo(User::class, 'uploadedByUserId'); }
public function galleryImages(): HasMany { return $this->hasMany(BusinessGalleryImage::class, 'mediaAssetId'); }
}
+24
View File
@@ -0,0 +1,24 @@
<?php
namespace App\Models;
use App\Enums\NotificationType;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Notification extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'Notification';
protected $fillable = ['businessId', 'recipientUserId', 'recipientCustomerId', 'type', 'appointmentId', 'loyaltyRewardId', 'subject', 'bodyText', 'deepLinkPath', 'idempotencyKey', 'readAt'];
protected function casts(): array { return ['type' => NotificationType::class, 'readAt' => 'datetime']; }
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
public function recipientUser(): BelongsTo { return $this->belongsTo(User::class, 'recipientUserId'); }
public function recipientCustomer(): BelongsTo { return $this->belongsTo(CustomerProfile::class, 'recipientCustomerId'); }
public function appointment(): BelongsTo { return $this->belongsTo(Appointment::class, 'appointmentId'); }
public function loyaltyReward(): BelongsTo { return $this->belongsTo(LoyaltyReward::class, 'loyaltyRewardId'); }
public function deliveries(): HasMany { return $this->hasMany(NotificationDelivery::class, 'notificationId'); }
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace App\Models;
use App\Enums\{NotificationChannel, NotificationDeliveryStatus};
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class NotificationDelivery extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'NotificationDelivery';
protected $fillable = ['notificationId', 'channel', 'status', 'scheduledFor', 'attemptCount', 'lastAttemptedAt', 'providerName', 'providerMessageId', 'failureReason', 'sentAt'];
protected function casts(): array { return ['channel' => NotificationChannel::class, 'status' => NotificationDeliveryStatus::class, 'scheduledFor' => 'datetime', 'lastAttemptedAt' => 'datetime', 'sentAt' => 'datetime']; }
public function notification(): BelongsTo { return $this->belongsTo(Notification::class, 'notificationId'); }
}
+19
View File
@@ -0,0 +1,19 @@
<?php
namespace App\Models;
use App\Enums\{NotificationChannel, NotificationType};
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class NotificationPreference extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'NotificationPreference';
protected $fillable = ['businessId', 'userId', 'type', 'channel', 'isEnabled'];
protected function casts(): array { return ['type' => NotificationType::class, 'channel' => NotificationChannel::class, 'isEnabled' => 'boolean']; }
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
public function user(): BelongsTo { return $this->belongsTo(User::class, 'userId'); }
}
+20
View File
@@ -0,0 +1,20 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class PushSubscription extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'PushSubscription';
protected $fillable = ['businessId', 'userId', 'customerId', 'endpoint', 'p256dhKey', 'authKey', 'deviceLabel', 'lastUsedAt', 'revokedAt'];
protected $hidden = ['p256dhKey', 'authKey'];
protected function casts(): array { return ['lastUsedAt' => 'datetime', 'revokedAt' => 'datetime']; }
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
public function user(): BelongsTo { return $this->belongsTo(User::class, 'userId'); }
public function customer(): BelongsTo { return $this->belongsTo(CustomerProfile::class, 'customerId'); }
}
+17
View File
@@ -0,0 +1,17 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Review extends Model
{
use UsesStringIds;
public const CREATED_AT = 'createdAt'; public const UPDATED_AT = 'updatedAt';
protected $table = 'Review';
protected $fillable = ['businessId', 'externalId', 'authorName', 'authorPhotoUrl', 'rating', 'text', 'relativeTimeDescription', 'publishedAt', 'isHidden', 'fetchedAt'];
protected function casts(): array { return ['publishedAt' => 'datetime', 'fetchedAt' => 'datetime', 'isHidden' => 'boolean']; }
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
}
+20
View File
@@ -0,0 +1,20 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Role extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'Role';
protected $fillable = ['businessId', 'name', 'isSystem'];
protected function casts(): array { return ['isSystem' => 'boolean']; }
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
public function permissions(): HasMany { return $this->hasMany(RolePermission::class, 'roleId'); }
public function staff(): HasMany { return $this->hasMany(StaffProfile::class, 'roleId'); }
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace App\Models;
use App\Enums\Permission;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class RolePermission extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'RolePermission';
protected $fillable = ['roleId', 'permission'];
protected function casts(): array { return ['permission' => Permission::class]; }
public function role(): BelongsTo { return $this->belongsTo(Role::class, 'roleId'); }
}
+26
View File
@@ -0,0 +1,26 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Service extends Model
{
use UsesStringIds;
public const CREATED_AT = 'createdAt';
public const UPDATED_AT = 'updatedAt';
protected $table = 'Service';
protected $fillable = ['businessId', 'categoryId', 'name', 'description', 'imageUrl', 'durationMinutes', 'price', 'bufferBeforeMinutes', 'bufferAfterMinutes', 'isActive', 'allowOnlineBooking', 'displayOrder'];
protected function casts(): array { return ['price' => 'decimal:2', 'isActive' => 'boolean', 'allowOnlineBooking' => 'boolean']; }
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
public function category(): BelongsTo { return $this->belongsTo(ServiceCategory::class, 'categoryId'); }
public function staff(): BelongsToMany { return $this->belongsToMany(StaffProfile::class, 'StaffService', 'serviceId', 'staffId')->withPivot(['priceOverride', 'durationOverrideMinutes']); }
public function appointmentServices(): HasMany { return $this->hasMany(AppointmentService::class, 'serviceId'); }
public function loyaltyEligibleFor(): HasMany { return $this->hasMany(LoyaltyEligibleService::class, 'serviceId'); }
public function loyaltyProgrammesUsingAsFreeReward(): HasMany { return $this->hasMany(LoyaltyProgramme::class, 'freeServiceId'); }
}
+21
View File
@@ -0,0 +1,21 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class ServiceCategory extends Model
{
use UsesStringIds;
public const CREATED_AT = 'createdAt';
public const UPDATED_AT = 'updatedAt';
protected $table = 'ServiceCategory';
protected $fillable = ['businessId', 'name', 'displayOrder', 'isActive'];
protected function casts(): array { return ['isActive' => 'boolean']; }
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
public function services(): HasMany { return $this->hasMany(Service::class, 'categoryId'); }
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class StaffBreak extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'Break';
protected $fillable = ['staffId', 'label', 'startMinutes', 'endMinutes'];
public function staff(): BelongsTo { return $this->belongsTo(StaffProfile::class, 'staffId'); }
public function days(): HasMany { return $this->hasMany(BreakDay::class, 'breakId'); }
}
+21
View File
@@ -0,0 +1,21 @@
<?php
namespace App\Models;
use App\Enums\CalendarProvider;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class StaffCalendarConnection extends Model
{
use UsesStringIds;
public const CREATED_AT = 'createdAt'; public const UPDATED_AT = 'updatedAt';
protected $table = 'StaffCalendarConnection';
protected $fillable = ['staffId', 'provider', 'externalAccountId', 'accountEmail', 'encryptedAccessToken', 'encryptedRefreshToken', 'tokenExpiresAt', 'selectedCalendarId', 'selectedCalendarName', 'connectedAt', 'lastSyncAt', 'lastSyncError', 'revokedAt'];
protected $hidden = ['encryptedAccessToken', 'encryptedRefreshToken'];
protected function casts(): array { return ['provider' => CalendarProvider::class, 'tokenExpiresAt' => 'datetime', 'connectedAt' => 'datetime', 'lastSyncAt' => 'datetime', 'revokedAt' => 'datetime']; }
public function staff(): BelongsTo { return $this->belongsTo(StaffProfile::class, 'staffId'); }
public function events(): HasMany { return $this->hasMany(AppointmentCalendarEvent::class, 'connectionId'); }
}
+19
View File
@@ -0,0 +1,19 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class StaffInvitation extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'StaffInvitation';
protected $fillable = ['businessId', 'staffId', 'email', 'token', 'invitedByUserId', 'expiresAt', 'acceptedAt'];
protected function casts(): array { return ['expiresAt' => 'datetime', 'acceptedAt' => 'datetime']; }
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
public function staff(): BelongsTo { return $this->belongsTo(StaffProfile::class, 'staffId'); }
public function invitedByUser(): BelongsTo { return $this->belongsTo(User::class, 'invitedByUserId'); }
}
+41
View File
@@ -0,0 +1,41 @@
<?php
namespace App\Models;
use App\Enums\StaffStatus;
use App\Enums\Permission;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
class StaffProfile extends Model
{
use UsesStringIds;
public const CREATED_AT = 'createdAt';
public const UPDATED_AT = 'updatedAt';
protected $table = 'StaffProfile';
protected $fillable = ['userId', 'businessId', 'roleId', 'bio', 'status', 'isBookableOnline'];
protected function casts(): array { return ['status' => StaffStatus::class, 'isBookableOnline' => 'boolean']; }
public function user(): BelongsTo { return $this->belongsTo(User::class, 'userId'); }
public function business(): BelongsTo { return $this->belongsTo(Business::class, 'businessId'); }
public function role(): BelongsTo { return $this->belongsTo(Role::class, 'roleId'); }
public function services(): BelongsToMany { return $this->belongsToMany(Service::class, 'StaffService', 'staffId', 'serviceId')->withPivot(['priceOverride', 'durationOverrideMinutes']); }
public function workingHours(): HasMany { return $this->hasMany(WorkingHours::class, 'staffId'); }
public function breaks(): HasMany { return $this->hasMany(StaffBreak::class, 'staffId'); }
public function timeOff(): HasMany { return $this->hasMany(TimeOff::class, 'staffId'); }
public function appointments(): HasMany { return $this->hasMany(Appointment::class, 'staffId'); }
public function invitation(): HasOne { return $this->hasOne(StaffInvitation::class, 'staffId'); }
public function calendarConnection(): HasOne { return $this->hasOne(StaffCalendarConnection::class, 'staffId'); }
public function authoredLoyaltyTransactions(): HasMany { return $this->hasMany(LoyaltyTransaction::class, 'authoredByStaffId'); }
public function authoredCustomerNotes(): HasMany { return $this->hasMany(CustomerNote::class, 'authorStaffId'); }
public function redeemedLoyaltyRewards(): HasMany { return $this->hasMany(LoyaltyReward::class, 'redeemedByStaffId'); }
public function hasPermission(Permission $permission): bool
{
return $this->role?->permissions->contains('permission', $permission) ?? false;
}
}
+15
View File
@@ -0,0 +1,15 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
class StaffService extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'StaffService';
protected $fillable = ['staffId', 'serviceId', 'priceOverride', 'durationOverrideMinutes'];
protected function casts(): array { return ['priceOverride' => 'decimal:2']; }
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace App\Models;
use App\Enums\TimeOffStatus;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class TimeOff extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'TimeOff';
protected $fillable = ['staffId', 'startDate', 'endDate', 'reason', 'status', 'startMinutes', 'endMinutes'];
protected function casts(): array { return ['startDate' => 'date', 'endDate' => 'date', 'status' => TimeOffStatus::class]; }
public function staff(): BelongsTo { return $this->belongsTo(StaffProfile::class, 'staffId'); }
}
+72
View File
@@ -0,0 +1,72 @@
<?php
namespace App\Models;
use Database\Factories\UserFactory;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasMany as UserHasMany;
class User extends Authenticatable
{
/** @use HasFactory<UserFactory> */
use HasFactory, Notifiable, UsesStringIds;
public const CREATED_AT = 'createdAt';
public const UPDATED_AT = 'updatedAt';
protected $table = 'User';
protected $keyType = 'string';
public $incrementing = false;
protected $fillable = [
'name', 'email', 'phone', 'passwordHash', 'isSuperAdmin',
];
protected $hidden = ['passwordHash', 'remember_token'];
public function getAuthPasswordName(): string
{
return 'passwordHash';
}
public function getAuthPassword(): ?string
{
return $this->passwordHash;
}
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'emailVerified' => 'datetime',
'phoneVerified' => 'datetime',
'isSuperAdmin' => 'boolean',
];
}
public function customerProfiles(): HasMany
{
return $this->hasMany(CustomerProfile::class, 'userId');
}
public function staffProfiles(): HasMany
{
return $this->hasMany(StaffProfile::class, 'userId');
}
public function receivedNotifications(): UserHasMany { return $this->hasMany(Notification::class, 'recipientUserId'); }
public function notificationPreferences(): UserHasMany { return $this->hasMany(NotificationPreference::class, 'userId'); }
public function pushSubscriptions(): UserHasMany { return $this->hasMany(PushSubscription::class, 'userId'); }
public function uploadedMediaAssets(): UserHasMany { return $this->hasMany(MediaAsset::class, 'uploadedByUserId'); }
public function sentStaffInvitations(): UserHasMany { return $this->hasMany(StaffInvitation::class, 'invitedByUserId'); }
}
+15
View File
@@ -0,0 +1,15 @@
<?php
namespace App\Models;
use App\Models\Concerns\UsesStringIds;
use Illuminate\Database\Eloquent\Model;
class WorkingHours extends Model
{
use UsesStringIds;
public $timestamps = false;
protected $table = 'WorkingHours';
protected $fillable = ['staffId', 'dayOfWeek', 'isOff', 'startMinutes', 'endMinutes'];
protected function casts(): array { return ['isOff' => 'boolean']; }
}