Skip to content

chore: sync conventions, tooling, and tests#402

Open
gvieira18 wants to merge 21 commits into
4.xfrom
chore/project-sync
Open

chore: sync conventions, tooling, and tests#402
gvieira18 wants to merge 21 commits into
4.xfrom
chore/project-sync

Conversation

@gvieira18

@gvieira18 gvieira18 commented Jul 8, 2026

Copy link
Copy Markdown
Member

📄 Visual overview of this PR — one-screen interactive summary of every change.

Note

Why tests/.pest/shards.json is committed — it's intentional. Pest v4.6.0 balances the suite across shards using recorded per-test timings. Committing this baseline (instead of regenerating it every run) makes the split deterministic and evenly balanced from the first CI run — no warm-up pass and no cross-run artifact upload to wire up. It's refreshed automatically as the suite grows. See Time-based sharding in Pest v4.6.0.

Summary

  • Guidelines — sync AI guidelines to he4rt conventions (namespace/naming, issue-tracker repo he4rt/heartdevs.com, added typed-JSON-cast + enum-contract guidance); drop 3 stale docs/agents/* mirrors.
  • Modular — fix make:module stubs + config/app-modules.php so a module's ServiceProvider scaffolds at src/ root (not Providers/); migrate squads and onboarding to match.
  • Testing DX — add tracked .env.testing.example, untrack the per-dev .env.testing, bootstrap it via post-root-package-install; use LazilyRefreshDatabase for feature tests.
  • CI — run the Pest suite in 2 balanced shards (committed timings baseline); gate the pipeline on canonical branch prefixes (feature/**, bugfix/**, chore/**, story/**, *.x).
  • Deps — pin intra-repo he4rt/* modules to ^1.0.0; bump dependencies.
  • Refactor — apply the Rector named-argument convention across models, commands, jobs and Livewire components.
  • Cleanup — remove 24 redundant .gitkeep placeholders.

Test plan

  • composer check — Rector, Pint, PHPStan all clean
  • php artisan test — 881 pass (539 feature + 342 unit, 2515 assertions)
  • Fresh clone: make setup creates .env.testing; make setup-test-db migrates it
  • Scaffolding a new module places its ServiceProvider at src/ root

gvieira18 added 10 commits July 8, 2026 12:16
Apply the project Rector named-argument rule across models,
commands, jobs and Livewire components.
Scaffold the module ServiceProvider at src/ root instead of a
Providers/ subdir, and migrate squads and onboarding to match.
Add a shard-aware Pest plugin with a committed timings baseline,
exclude it from Rector/PHPStan, and split CI tests into 2 shards.
Ship a tracked .env.testing.example, untrack the per-dev
.env.testing, and bootstrap it on setup.
Defer each feature test's wrapping transaction to the first query
instead of opening it eagerly in setUp. Full suite green: 881 tests.
@gvieira18 gvieira18 requested a review from a team July 8, 2026 22:37
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Guidelines, testing infrastructure, and CI were expanded for module dependency rules, typed JSON casts, enum Filament contracts, issue tracking, and branch naming. Test execution now uses a Pest shard plugin, sharded GitHub Actions, updated Composer scripts, and refreshed shard timing data. Onboarding and squads service providers moved out of Providers namespaces. Many model, command, job, and Livewire attributes were converted to named-argument syntax.

Possibly related PRs

Suggested reviewers: danielhe4rt

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the PR’s main themes: conventions, tooling, and tests.
Description check ✅ Passed The description is clearly aligned with the changeset and summarizes the same convention, CI, and testing updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (1)
app/Support/PestShardPlugin.php (1)

533-557: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Unchecked file_put_contents in writeTimings() silently loses timing data.

If the write fails (disk full, permissions), the canonical shards.json is not updated and subsequent sharded runs use stale timings with no error signal. Same issue in writeWorkerTimings() at line 394.

♻️ Proposed fix
-        file_put_contents($path, json_encode([
+        $result = file_put_contents($path, json_encode([
             'timings' => $timings,
             'checksum' => md5(implode("\n", $canonical)),
             'updated_at' => date('c'),
         ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)."\n");
+
+        if ($result === false) {
+            throw new InvalidOption('Failed to write [tests/.pest/shards.json]. Check directory permissions.');
+        }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/Support/PestShardPlugin.php` around lines 533 - 557, `writeTimings()` is
ignoring the result of `file_put_contents`, so timing updates can fail silently
and leave stale shard data; update `writeTimings()` to check the write result
and surface a clear failure when the file cannot be written. Apply the same
safeguard in `writeWorkerTimings()` as noted in the comment, using the existing
shard-writing flow around `shardsPath()` and the JSON payload generation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.ai/guidelines/domain/06-typed-json-casts.blade.php:
- Around line 36-38: The example has inconsistent cast names between the prose
and snippet, which can mislead readers copying the wrong class. Update the
guidance around AsIdentityMetadata so the descriptive text and the example use
the same class name throughout, and keep the reference aligned with the typed VO
cast shown in the snippet.

In @.ai/guidelines/domain/07-enum-filament-contracts.blade.php:
- Around line 64-71: The ordered example in getColor() does not match the
documented light-to-red ramp because Analyst is mapped to blue. Update the
getColor() match in the enum contract example so the ordered cases follow the
same ramp (or, if that cannot be expressed, change the example to an unordered
enum), keeping the mapping consistent with the comment and the enum’s intent.

In @.ai/guidelines/workflow/01-issue-tracker.blade.php:
- Around line 13-22: The example issue creation command is missing the required
difficulty label even though the workflow text says
triage/type/module/difficulty labels are mandatory. Update the sample under the
issue creation snippet to include a difficulty label alongside the existing type
and module labels, using the same gh issue create example so it matches the
guidance in workflow/triage-labels.

In @.env.testing.example:
- Line 3: The example environment file currently ships a real APP_KEY value,
which should not be committed. Replace the concrete key in the
.env.testing.example entry with a non-secret placeholder so contributors
generate their own value, and keep the change limited to the APP_KEY constant in
the example config.

In `@app/Support/PestShardPlugin.php`:
- Around line 207-209: The PestShardPlugin logic in the empty-tests path is
falling back to the original arguments, which causes a shard with no assigned
tests to run the full suite. Update the shard argument building flow in
PestShardPlugin so that when testsToRun is empty it returns a configuration that
executes zero tests for that shard instead of omitting --filter, and verify the
behavior in the code path around the test selection and arguments assembly.

In `@Makefile`:
- Line 68: The setup-test-db target currently runs only the migrate step, which
assumes test_heartdevs already exists and causes first-time setup to fail.
Update the Makefile’s setup-test-db recipe to create the testing database before
calling php artisan migrate --env=testing, keeping the existing migration
command in place and ensuring the full setup path works from a clean
environment.

---

Nitpick comments:
In `@app/Support/PestShardPlugin.php`:
- Around line 533-557: `writeTimings()` is ignoring the result of
`file_put_contents`, so timing updates can fail silently and leave stale shard
data; update `writeTimings()` to check the write result and surface a clear
failure when the file cannot be written. Apply the same safeguard in
`writeWorkerTimings()` as noted in the comment, using the existing shard-writing
flow around `shardsPath()` and the JSON payload generation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 5f06e8dc-e0c3-448d-9619-c71584757bfb

📥 Commits

Reviewing files that changed from the base of the PR and between b6393d5 and e42a5b4.

⛔ Files ignored due to path filters (2)
  • composer.lock is excluded by !**/*.lock
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (95)
  • .ai/guidelines/domain/02-module-architecture.blade.php
  • .ai/guidelines/domain/06-typed-json-casts.blade.php
  • .ai/guidelines/domain/07-enum-filament-contracts.blade.php
  • .ai/guidelines/workflow/01-issue-tracker.blade.php
  • .ai/guidelines/workflow/04-branch-naming.blade.php
  • .env.testing
  • .env.testing.example
  • .github/workflows/_pest.yml
  • .github/workflows/continuous-integration.yml
  • .gitignore
  • Makefile
  • app-modules/activity/database/factories/.gitkeep
  • app-modules/activity/database/migrations/.gitkeep
  • app-modules/activity/src/Moderation/Models/ModerationEvent.php
  • app-modules/activity/src/Voice/Models/Voice.php
  • app-modules/community/database/factories/.gitkeep
  • app-modules/community/database/migrations/.gitkeep
  • app-modules/docs/src/Console/Commands/CacheDocsCommand.php
  • app-modules/economy/database/factories/.gitkeep
  • app-modules/economy/database/migrations/.gitkeep
  • app-modules/gamification/database/factories/.gitkeep
  • app-modules/gamification/database/migrations/.gitkeep
  • app-modules/gamification/database/seeders/.gitkeep
  • app-modules/identity/database/factories/.gitkeep
  • app-modules/identity/database/migrations/.gitkeep
  • app-modules/identity/src/Tenant/Models/TenantUser.php
  • app-modules/identity/src/User/Models/User.php
  • app-modules/integration-devto/src/Polling/SyncDevToArticles.php
  • app-modules/integration-discord/database/factories/.gitkeep
  • app-modules/integration-discord/database/migrations/.gitkeep
  • app-modules/integration-discord/src/ETL/Console/BackfillVoiceLogsCommand.php
  • app-modules/integration-discord/src/ETL/Console/ImportDiscordMessagesCommand.php
  • app-modules/integration-discord/src/ETL/Console/ImportDiscordProfilesCommand.php
  • app-modules/integration-discord/src/ETL/Console/MergeDuplicateDiscordProfilesCommand.php
  • app-modules/integration-discord/src/Sync/Console/PurgeUnusedInvitesCommand.php
  • app-modules/integration-discord/src/Sync/Console/SyncDiscordGuildCommand.php
  • app-modules/integration-github/database/factories/.gitkeep
  • app-modules/integration-github/database/migrations/.gitkeep
  • app-modules/integration-github/src/Backfill/Jobs/BackfillGithubRepository.php
  • app-modules/integration-github/src/Console/BackfillGithubCommand.php
  • app-modules/integration-github/tests/Feature/.gitkeep
  • app-modules/integration-twitch/database/migrations/.gitkeep
  • app-modules/integration-twitch/src/Console/LinkTwitchChannelCommand.php
  • app-modules/integration-twitch/src/Console/SubscribeTwitchEventsCommand.php
  • app-modules/integration-whatsapp/src/Models/WhatsAppEventLog.php
  • app-modules/moderation/src/Appeals/ModerationAppeal.php
  • app-modules/moderation/src/Audit/ModerationAuditLog.php
  • app-modules/moderation/src/Cases/Models/ModerationCase.php
  • app-modules/moderation/src/Cases/Models/ModerationReport.php
  • app-modules/moderation/src/Classification/Jobs/ClassifyAndRoute.php
  • app-modules/moderation/src/Classification/Jobs/ScreenContent.php
  • app-modules/moderation/src/Enforcement/ModerationAction.php
  • app-modules/moderation/src/Rules/ModerationRule.php
  • app-modules/moderation/tests/Feature/.gitkeep
  • app-modules/moderation/tests/Unit/.gitkeep
  • app-modules/onboarding/composer.json
  • app-modules/onboarding/src/OnboardingServiceProvider.php
  • app-modules/panel-admin/resources/views/.gitkeep
  • app-modules/panel-admin/tests/Feature/.gitkeep
  • app-modules/panel-app/src/Livewire/Timeline/Feed.php
  • app-modules/panel-app/src/Livewire/Timeline/PostShow.php
  • app-modules/panel-app/src/Livewire/Timeline/ThreadReplies.php
  • app-modules/panel-app/src/Pages/ProfilePage.php
  • app-modules/portal/src/Livewire/CommunityRetrospectivePage.php
  • app-modules/portal/src/Livewire/Homepage.php
  • app-modules/portal/src/Livewire/SocialLinksPage.php
  • app-modules/portal/src/Retrospective/CommunityRetrospective.php
  • app-modules/profile/src/Models/Profile.php
  • app-modules/profile/src/Models/WorkExperience.php
  • app-modules/squads/composer.json
  • app-modules/squads/src/SquadsServiceProvider.php
  • app/Console/Commands/AnalyzeDiscordProfiles.php
  • app/Console/Commands/CommunityReport.php
  • app/Console/Commands/FetchDiscordMembers.php
  • app/Console/Commands/FetchDiscordProfile.php
  • app/Console/Commands/FetchDiscordProfiles.php
  • app/Console/Commands/FixPostSwitchTimestampsCommand.php
  • app/Console/Commands/GenerateDiscordTenant.php
  • app/Console/Commands/ImportDiscordMembers.php
  • app/Support/PestShardPlugin.php
  • composer.json
  • config/app-modules.php
  • database/factories/.gitkeep
  • docs/agents/domain.md
  • docs/agents/issue-tracker.md
  • docs/agents/triage-labels.md
  • package.json
  • phpstan.neon
  • phpunit.xml
  • rector.php
  • stubs/app-modules/.gitkeep
  • stubs/app-modules/ServiceProvider.php
  • stubs/app-modules/composer-stub.json
  • tests/.pest/shards.json
  • tests/Feature/.gitkeep
💤 Files with no reviewable changes (4)
  • docs/agents/issue-tracker.md
  • docs/agents/domain.md
  • phpunit.xml
  • docs/agents/triage-labels.md

Comment thread .ai/guidelines/domain/06-typed-json-casts.blade.php
Comment thread .ai/guidelines/domain/07-enum-filament-contracts.blade.php
Comment thread .ai/guidelines/workflow/01-issue-tracker.blade.php
Comment thread .env.testing.example Outdated
Comment thread app/Support/PestShardPlugin.php
Comment thread Makefile
gvieira18 added 3 commits July 8, 2026 20:23
It's a per-developer, gitignored file; the tracked template lives in
.env.testing.example. It was committed by mistake earlier on this branch.
- Empty APP_KEY in the tracked .env.testing.example (CodeRabbit); generate
  it per env via a shared composer key:generate script (app + testing),
  run before migrate in setup.
- Make/Task/CI delegate to composer scripts (single source of truth).
- Sync post-autoload-dump with the standard hooks: filament:upgrade,
  modules:sync, pre-package-uninstall.
Add the standard hooks both sibling projects run: filament:upgrade,
modules:sync (--no-phpunit), and pre-package-uninstall.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
Makefile (1)

68-68: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

setup-test-db still lacks database creation step.

php artisan migrate --env=testing requires test_heartdevs to already exist. First-time make setup-test-db fails on a clean environment. This was previously flagged and remains unresolved.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Makefile` at line 68, The setup-test-db target still runs migrate before
ensuring the testing database exists, so clean environments fail on first run.
Update the Makefile’s setup-test-db flow to create the test_heartdevs database
before the php artisan migrate --env=testing --no-interaction --force step,
keeping the database creation logic in the same target or a helper it calls.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@Makefile`:
- Line 68: The setup-test-db target still runs migrate before ensuring the
testing database exists, so clean environments fail on first run. Update the
Makefile’s setup-test-db flow to create the test_heartdevs database before the
php artisan migrate --env=testing --no-interaction --force step, keeping the
database creation logic in the same target or a helper it calls.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 755f9534-4871-40eb-981b-7518bf167853

📥 Commits

Reviewing files that changed from the base of the PR and between e42a5b4 and 7105d49.

📒 Files selected for processing (5)
  • .env.testing.example
  • .github/workflows/_pest.yml
  • Makefile
  • Taskfile.yml
  • composer.json

@gvieira18 gvieira18 marked this pull request as draft July 8, 2026 23:56
@gvieira18 gvieira18 marked this pull request as ready for review July 9, 2026 00:12
Clintonrocha98
Clintonrocha98 previously approved these changes Jul 9, 2026
gvieira18 added 2 commits July 9, 2026 08:16
The gate used if: !cancelled() with two steps that only tested for
'failure'/'cancelled' in needs.*.result. When Setup PHP is cancelled,
downstream checks become 'skipped' — neither string matched, so the
gate reported all-green without a single check running (PR #402 run
28997719361, attempt 1).

Switch to always() so the gate always decides, and whitelist success:
any failure/cancelled/skipped result now fails the gate. Skip only on
draft PRs, matching the checks' own draft guard.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants