*/ use HasFactory; /** * Columns owned by the sync process rather than by a human. Kept out of * the fillable list above so a stray form submission cannot fake stats. * * @var array */ public const SYNCED_COLUMNS = [ 'html_url', 'description', 'homepage', 'default_branch', 'primary_language', 'license', 'topics', 'languages', 'stars', 'forks', 'watchers', 'open_issues_count', 'contributors_count', 'commits_last_year', 'is_archived', 'is_fork', 'pushed_at', 'repo_created_at', ]; protected function casts(): array { return [ 'provider' => GitProvider::class, 'topics' => 'array', 'languages' => 'array', 'is_primary' => 'boolean', 'show_publicly' => 'boolean', 'is_archived' => 'boolean', 'is_fork' => 'boolean', 'pushed_at' => 'datetime', 'repo_created_at' => 'datetime', 'last_synced_at' => 'datetime', ]; } /** * @return BelongsTo */ public function project(): BelongsTo { return $this->belongsTo(Project::class); } /** * @return HasMany */ public function issues(): HasMany { return $this->hasMany(RepositoryIssue::class); } /** * Issues suitable for someone who has never contributed before. * * @return HasMany */ public function goodFirstIssues(): HasMany { return $this->issues()->where('is_good_first_issue', true); } public function owner(): string { return str_contains($this->full_name, '/') ? explode('/', $this->full_name)[0] : $this->full_name; } public function name(): string { return str_contains($this->full_name, '/') ? explode('/', $this->full_name, 2)[1] : $this->full_name; } /** * A repository is considered dormant when nothing has been pushed for a * while. The public site uses this to avoid advertising dead work as live. */ public function isDormant(int $days = 180): bool { return $this->pushed_at === null || $this->pushed_at->lt(now()->subDays($days)); } public function hasSyncedSuccessfully(): bool { return $this->last_synced_at !== null && blank($this->sync_error); } /** * @param Builder<$this> $query * @return Builder<$this> */ public function scopePubliclyVisible(Builder $query): Builder { return $query->where('show_publicly', true); } /** * Repositories whose sync keeps failing, so the panel can flag them rather * than silently showing stale numbers forever. * * @param Builder<$this> $query * @return Builder<$this> */ public function scopeFailing(Builder $query): Builder { return $query->where('sync_failures', '>=', 3); } }