Repository navigation
feat: refine hot topics headlines and flame #1436
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
be09756
f12d66e
52af28a
9e88765
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace App\Queries; | ||
|
|
||
| use App\Models\Commit; | ||
| use App\Models\Headline; | ||
| use App\Models\User; | ||
| use Illuminate\Database\Eloquent\Builder; | ||
| use Illuminate\Support\Collection; | ||
|
|
||
| final readonly class HeadlineSummaryQuery | ||
| { | ||
| public function get(Headline $headline, User $viewer): ?string | ||
| { | ||
| return $this->getMany([$headline->id], $viewer)->get($headline->id); | ||
| } | ||
|
|
||
| /** | ||
| * @param list<string> $headlineIds | ||
| * @return Collection<string, string|null> | ||
| */ | ||
| public function getMany(array $headlineIds, User $viewer): Collection | ||
| { | ||
| // Without stored provenance, check all linked posts rather than risk repeating a hidden author's words. | ||
| return Headline::query()->whereKey($headlineIds) | ||
| ->whereNotNull('summary') | ||
| ->where('summary_created_at', '>', now()->subHours(Headline::SUMMARY_HOURS)) | ||
| ->whereDoesntHave('commits', fn (Builder $query): Builder => $query->topLevel()->approved() | ||
| ->whereNotIn('commits.id', Commit::query()->select('commits.id')->visibleTo($viewer)->withoutMutedAuthorsFor($viewer))) | ||
| ->get() | ||
| ->mapWithKeys(fn (Headline $headline): array => [$headline->id => $headline->summary]); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace Database\Seeders; | ||
|
|
||
| use App\Actions\UpdateCommitEmbedding; | ||
| use App\Models\Commit; | ||
| use App\Models\Headline; | ||
| use App\Models\User; | ||
| use Illuminate\Database\Seeder; | ||
| use Illuminate\Support\Facades\DB; | ||
|
|
||
| final class HeadlineSeeder extends Seeder | ||
| { | ||
| public function __construct(private readonly UpdateCommitEmbedding $updateCommitEmbedding) | ||
| { | ||
| // | ||
| } | ||
|
|
||
| public function run(): void | ||
| { | ||
| DB::transaction(function (): void { | ||
| $users = collect([0, 1])->map(fn (int $index): User => User::query()->firstWhere('github_id', "headline-seed-{$index}") | ||
| ?? User::factory()->create(['github_id' => "headline-seed-{$index}"])); | ||
| $topics = [ | ||
| ['Database indexing', 'Developers compare composite and partial indexes to speed up queries without adding unnecessary write overhead.', [ | ||
| 'A composite index on tenant_id and created_at took our activity query from 240 ms to 12 ms. The query plan finally stopped scanning the whole table.', | ||
| 'Trying partial indexes for queued jobs in PostgreSQL. Indexing only the pending rows keeps the index small even as completed jobs pile up.', | ||
| ]], | ||
| ['Accessible developer tools', 'Keyboard navigation and screen-reader support are getting attention in editors, terminals and other developer tools.', [ | ||
| 'Shipped keyboard navigation for our command palette. Every action now works without a mouse, including nested menus and search results.', | ||
| 'Testing our terminal UI with a screen reader found three unlabeled buttons. Accessibility checks are going into the release checklist.', | ||
| ]], | ||
| ['Laravel community updates and upcoming releases', 'The community shares upgrade notes and practical examples of queues, typed configuration and concurrency.', [ | ||
| 'Our Laravel upgrade is ready. Typed configuration caught a missing setting before deploy, and the full test suite stayed green.', | ||
| 'Using Laravel concurrency for independent imports cut our dashboard refresh time in half. Writing up the trade-offs for the next meetup.', | ||
| ]], | ||
| ['Open-source maintenance', null, [ | ||
| 'Opened a good first issue for improving the installation guide. Small documentation fixes are a great way to start contributing.', | ||
| 'Set aside Friday afternoon for reviewing community pull requests. Keeping the review queue moving matters as much as shipping new features.', | ||
| ]], | ||
| ['Browser performance', 'Teams explore ways to avoid layout shifts, reduce JavaScript work and keep scrolling smooth on slower devices.', [ | ||
| 'Reserved the image dimensions in our feed and removed a layout shift on first load. The fix was two attributes, not another JavaScript observer.', | ||
| 'Profiling our scrolling list on a slower laptop exposed expensive work in every row. Moving that work out of render made the feed noticeably smoother.', | ||
| ]], | ||
| ]; | ||
|
|
||
| foreach ($topics as [$name, $summary, $bodies]) { | ||
| $headline = Headline::query()->updateOrCreate(['name' => $name], [ | ||
| 'summary' => $summary, | ||
| 'summary_created_at' => $summary === null ? null : now(), | ||
| ]); | ||
|
|
||
| foreach ($users as $index => $user) { | ||
| $attributes = [ | ||
| 'body' => $bodies[$index], | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addressed and folded into the seed-fixtures commit. New seeded discussions receive embeddings through UpdateCommitEmbedding, using the existing network-free local provider. Both seeder cases now request all five real headline pages and assert that their linked discussions are returned. Targeted seeder/headline/embedding tests passed, as did the full suite. |
||
| 'created_at' => now()->subMinutes(15 + $index * 30), | ||
| ]; | ||
| $commit = Commit::query()->whereBelongsTo($user)->firstWhere('body', $attributes['body']) | ||
| ?? Commit::factory()->for($user)->make($attributes); | ||
| $commit->fill($attributes)->save(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| $headline->commits()->syncWithoutDetaching($commit); | ||
|
|
||
| $this->updateCommitEmbedding->handle($commit); | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed and folded into the recap commit. commitMutationOptions explicitly includes hotTopics for deletion/restoration refreshes, so the once-cached sidebar recap updates alongside the headline page. The existing options regression test now covers the requested prop; JavaScript tests pass (223 total).