feat(integration-devto): article scraping PoC#412
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository YAML (base), Central YAML (inherited) Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds a browser-console IIFE that validates dev.to 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 14
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
🟡 Minor comments (16)
.github/skills/configure-nightwatch/SKILL.md-38-38 (1)
38-38: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winSpecify the fenced-block language.
Use
textfor the ASCII flow diagram to satisfy MD040.🤖 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 @.github/skills/configure-nightwatch/SKILL.md at line 38, Update the fenced code block containing the ASCII flow diagram in SKILL.md to specify the `text` language after the opening fence, preserving the diagram content unchanged.Source: Linters/SAST tools
.github/skills/configure-nightwatch/reference.md-42-47 (1)
42-47: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick winRename this section. It only disables request-payload capture and redacts selected headers; other request metadata can still be collected.
🤖 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 @.github/skills/configure-nightwatch/reference.md around lines 42 - 47, Rename the “Disable sensitive data collection” section in the Nightwatch configuration reference to accurately describe that it disables request-payload capture and redacts selected headers, without implying that all request metadata collection is disabled..github/skills/configure-nightwatch/SKILL.md-60-72 (1)
60-72: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAdd scheduled-task sampling here.
NIGHTWATCH_SCHEDULED_TASK_SAMPLE_RATEis a separate control for scheduled Artisan tasks; listing onlyNIGHTWATCH_COMMAND_SAMPLE_RATEmakes this section misleading.🤖 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 @.github/skills/configure-nightwatch/SKILL.md around lines 60 - 72, Update the Global Sample Rates section in SKILL.md to list NIGHTWATCH_SCHEDULED_TASK_SAMPLE_RATE as a separate environment variable for scheduled Artisan tasks, including an appropriate default or recommendation consistent with the surrounding sampling settings..github/skills/configure-nightwatch/reference.md-3-15 (1)
3-15: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAdd rows for scheduled tasks and logs. This summary omits
Scheduled Tasks(NIGHTWATCH_SCHEDULED_TASK_SAMPLE_RATE) andLogs(NIGHTWATCH_LOG_LEVEL), so the table is incomplete unless its scope is narrowed.🤖 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 @.github/skills/configure-nightwatch/reference.md around lines 3 - 15, Add `Scheduled Tasks` and `Logs` rows to the “Configuration Summary by Event Type” table, documenting `NIGHTWATCH_SCHEDULED_TASK_SAMPLE_RATE` and `NIGHTWATCH_LOG_LEVEL` in their appropriate columns. Keep the existing event rows and table structure unchanged..github/skills/configure-nightwatch/reference.md-71-80 (1)
71-80: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winAdd
NIGHTWATCH_ENABLED=trueto the development checklist.NIGHTWATCH_REQUEST_SAMPLE_RATE=1.0still leaves collection off because both example env files defaultNIGHTWATCH_ENABLED=false.🤖 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 @.github/skills/configure-nightwatch/reference.md around lines 71 - 80, Add NIGHTWATCH_ENABLED=true to the development verification checklist alongside NIGHTWATCH_REQUEST_SAMPLE_RATE=1.0, so the checklist explicitly enables Nightwatch collection during development.composer.json-63-63 (1)
63-63: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winKeep
laravel/boostpinned to^2.4.12^2.4broadens the allowed range to older 2.4.x releases on future updates.🤖 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 `@composer.json` at line 63, Update the laravel/boost Composer constraint from ^2.4 to ^2.4.12, keeping the dependency pinned to that minimum patch release..github/skills/laravel-best-practices/rules/caching.md-21-27 (1)
21-27: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winDescribe
flexible()as deferred after the response, not background.
flexible()refreshes via Laravel’s deferred execution after the response, not an independent background worker.🤖 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 @.github/skills/laravel-best-practices/rules/caching.md around lines 21 - 27, Update the Cache::flexible() guidance in the stale-while-revalidate section to describe cache refreshing as deferred execution after the response, not as background processing. Adjust the explanation and example annotation while preserving the existing fresh and stale duration semantics..github/skills/laravel-best-practices/rules/style.md-34-36 (1)
34-36: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winQualify
first()->name→value('name').value()returns the raw column;first()->namecan apply Eloquent accessors and casts, so this is not a general replacement.🤖 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 @.github/skills/laravel-best-practices/rules/style.md around lines 34 - 36, Revise the `first()->name` to `value('name')` guidance in the style rule so it is not presented as a general replacement. Qualify that `value()` returns the raw column value, while `first()->name` may apply Eloquent accessors and casts, and preserve the recommendation only where raw-value behavior is intended..github/skills/laravel-best-practices/rules/events-notifications.md-3-5 (1)
3-5: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winDocument
__invokeand the discovery scope. Laravel also discovers__invoke(...)listeners, and only within configured discovery paths; listeners outside those paths still needwithEvents(discover: [...])or manual registration.🤖 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 @.github/skills/laravel-best-practices/rules/events-notifications.md around lines 3 - 5, Update the “Rely on Event Discovery” section to document that Laravel discovers both handle(EventType $event) and __invoke(...) listener methods, and clarify that discovery is limited to configured paths. State that listeners outside those paths require withEvents(discover: [...]) or manual registration..github/skills/laravel-best-practices/rules/blade-views.md-25-32 (1)
25-32: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAdd the matching
@fragment('user-list')block.fragmentIf()only returns a named fragment defined in the Blade view.🤖 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 @.github/skills/laravel-best-practices/rules/blade-views.md around lines 25 - 32, Update the Blade view example associated with the fragmentIf call to define a matching `@fragment`('user-list') block around the user-list markup. Keep the full-page rendering intact while ensuring the named fragment returned by fragmentIf is explicitly declared..github/skills/laravel-best-practices/rules/validation.md-60-70 (1)
60-70: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winGuard the stock check against a missing product.
Product::find($this->product_id)can returnnull, and a positivequantity > nullstill passes, so this callback can add a misleading “Not enough stock” error. Addexists:products,idor return early when no product is found.🤖 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 @.github/skills/laravel-best-practices/rules/validation.md around lines 60 - 70, Update the after() validation callback to handle a missing product before comparing quantity against stock, using the existing Product lookup; add the products.id existence validation or return early when Product::find($this->product_id) is null, while preserving the insufficient-stock error for existing products..github/skills/laravel-best-practices/rules/security.md-91-94 (1)
91-94: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick winCorrect the Inertia CSRF guidance.
@csrfis Blade-only; Inertia uses the XSRF cookie/header flow, not an automatically applied directive.🤖 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 @.github/skills/laravel-best-practices/rules/security.md around lines 91 - 94, Update the CSRF Protection guidance in security.md to remove the claim that Inertia automatically applies the Blade `@csrf` directive. State that `@csrf` applies only to Blade forms, while Inertia relies on the XSRF cookie/header flow..github/skills/laravel-best-practices/rules/queue-jobs.md-102-113 (1)
102-113: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winRemove the
$tries = 0requirement.retryUntil()already governs the retry deadline, so this example should not imply thattriesmust be zero.🤖 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 @.github/skills/laravel-best-practices/rules/queue-jobs.md around lines 102 - 113, Remove the `$tries = 0` declaration and the accompanying requirement from the `retryUntil()` guidance, leaving the example focused solely on the time-based retry deadline and preserving the existing `retryUntil()` implementation..github/skills/laravel-best-practices/rules/scheduling.md-11-13 (1)
11-13: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winLimit
runInBackground()tocommand()andexec()schedules. The current wording overgeneralizes; this method only applies to those scheduler types.🤖 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 @.github/skills/laravel-best-practices/rules/scheduling.md around lines 11 - 13, Update the “Use runInBackground() for Concurrent Long Tasks” guidance to state that runInBackground() applies only to schedules created with command() or exec(). Remove the broader implication that it works for all scheduler task types, while preserving the concurrency explanation..github/skills/laravel-best-practices/rules/http-client.md-111-119 (1)
111-119: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winCheck each pooled response before calling
json().Http::pool()still returnsResponseobjects that can be 4xx/5xx, so this example should callthrow()or guardjson()withsuccessful()for every response.🤖 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 @.github/skills/laravel-best-practices/rules/http-client.md around lines 111 - 119, Update the pooled response handling after Http::pool() so each named response—users, posts, and comments—is checked for success before calling json(). Use throw() or an equivalent successful() guard consistently for every response, preserving the existing response aliases and parsing behavior..github/skills/laravel-best-practices/rules/queue-jobs.md-3-5 (1)
3-5: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winRequire a few seconds of buffer between
retry_afterandtimeout. A minimal gap can still duplicate jobs during shutdown or scheduling overhead.🤖 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 @.github/skills/laravel-best-practices/rules/queue-jobs.md around lines 3 - 5, Update the “Set retry_after Greater Than timeout” guidance in queue-jobs.md to require a few seconds of buffer between retry_after and the job timeout, rather than merely requiring retry_after to be longer. Preserve the existing duplicate-execution warning and clearly state that the buffer accounts for shutdown and scheduling overhead.
🧹 Nitpick comments (6)
app-modules/integration-devto/docs/recipes/reactions-stats-scraper.js (3)
56-58: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winPotential null dereference on
informationElement.
detailsElement.children[0]can beundefinedif the element has no children. The optional chaining on line 57 (informationElement?.textContent) prevents a crash, butrawTextbecomes''andtypebecomesUNKNOWN_VALUE. This is a silent degradation — a malformed entry is reported asunknowntype rather than being filtered out likeextractReactiondoes for missingdetailsElement. Consider returningnullwheninformationElementis absent so it gets filtered byextractReactions.🤖 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-modules/integration-devto/docs/recipes/reactions-stats-scraper.js` around lines 56 - 58, Update the reaction extraction logic around informationElement so it returns null immediately when detailsElement.children[0] is absent, matching extractReaction’s handling of missing detailsElement and allowing extractReactions to filter the malformed entry instead of assigning UNKNOWN_VALUE.
96-113: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueFallback textarea not removed if
appendChildthrows.If
document.body.appendChildsucceeds butexecCommandthrows, thefinallyblock removes the textarea — good. However,textarea.focus()on line 103 is unnecessary beforeselect()and can cause focus-jumping on some browsers. Minor, butselect()alone suffices.🤖 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-modules/integration-devto/docs/recipes/reactions-stats-scraper.js` around lines 96 - 113, Remove the unnecessary textarea.focus() call from copyToClipboardFallback while preserving the existing select(), copy execution, and cleanup behavior.
14-14: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winFragile Tailwind-class-based selector.
.fs-sm.py-2.flex.items-centeris tightly coupled to dev.to's current Tailwind utility classes. Any class reordering or rename silently breaks extraction with no error — entries are just silently dropped. Consider adding a debug log whenextractReactionsreturns zero entries despite a container being found, to aid diagnosis.🤖 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-modules/integration-devto/docs/recipes/reactions-stats-scraper.js` at line 14, Add diagnostic logging around extractReactions so that when the reactions container is found but zero entries are extracted, it emits a debug message indicating the selector or extraction failure. Preserve the existing extraction behavior and avoid logging when the container is absent or entries were successfully found..github/skills/configure-nightwatch/SKILL.md (1)
321-331: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winClarify the capture scope. State that
NIGHTWATCH_CAPTURE_REQUEST_PAYLOAD=truecaptures request bodies only for exception events, not all requests.🤖 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 @.github/skills/configure-nightwatch/SKILL.md around lines 321 - 331, Update the “Redact request payloads” section to explicitly state that NIGHTWATCH_CAPTURE_REQUEST_PAYLOAD=true captures request bodies only for exception events, not for all requests..github/skills/laravel-best-practices/SKILL.md (1)
21-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDeclare supported Laravel versions before recommending version-sensitive APIs.
The rules reference
defer(),Context,Concurrency, and#[CollectedBy], but this skill does not define a minimum Laravel version or compatibility policy. Add version gates or require checking the project’s declared Laravel constraint before applying these examples. (laravel.com)🤖 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 @.github/skills/laravel-best-practices/SKILL.md around lines 21 - 25, Update the Laravel best-practices guidance to require identifying the project's declared Laravel version constraint before recommending or applying version-sensitive APIs such as defer(), Context, Concurrency, and #[CollectedBy]. Add explicit compatibility gates or version checks for these examples, while preserving the existing instruction to verify APIs against the installed framework..github/skills/laravel-best-practices/rules/events-notifications.md (1)
19-25: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winRelax the blanket queueing rule Queue notifications only when they do slow or external work; keep immediate or database-only notifications synchronous when needed, and note that queued notifications require a running worker.
🤖 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 @.github/skills/laravel-best-practices/rules/events-notifications.md around lines 19 - 25, Revise the “Always Queue Notifications” guidance to recommend queueing only notifications that perform slow or external work, while allowing immediate or database-only notifications to remain synchronous when appropriate. Update the InvoicePaid example and surrounding text to reflect this conditional guidance, and note that queued notifications require a running worker.
🤖 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 @.codex/config.toml:
- Around line 2-3: Update the MCP command configuration to remove the hardcoded
machine-specific `/home/sonse/heartdevs.com` path and `php8.5` executable, using
the repository’s portable project and PHP invocation mechanism instead. Preserve
the existing `boost:mcp` command and argument behavior while ensuring the
checked-in configuration works across WSL setups.
In @.github/skills/fluxui-development/SKILL.md:
- Line 3: Update the description metadata for the Flux UI skill to remove
date-pickers and kanban from the free-edition coverage list, or explicitly mark
both as Pro-only while keeping the remaining component coverage unchanged.
In @.github/skills/laravel-best-practices/rules/advanced-queries.md:
- Around line 61-75: Revise the “Prefer whereIn + Subquery Over whereHas”
guidance to remove the claim that whereIn() is universally more performant or
inherently index-friendly. Present whereHas() and whereIn() as alternatives
whose performance depends on the database optimizer and available indexes, and
instruct readers to verify the chosen query with appropriate indexes and EXPLAIN
output.
In @.github/skills/laravel-best-practices/rules/architecture.md:
- Around line 106-108: Update the query-level Product example using
lockForUpdate() so the select and subsequent operation execute inside an
explicit database transaction. Preserve the existing Product::where(...) lookup
while demonstrating that the lock remains active for the full transactional
operation.
- Around line 12-15: Update the handle method’s order-creation and
inventory-reservation workflow to execute database-backed operations inside
DB::transaction(), ensuring a reservation failure rolls back the persisted
order; if inventory is external, document and implement an appropriate outbox or
compensation flow instead.
- Around line 151-158: Update the middleware example around Context::add so
X-Tenant-ID is not trusted directly: resolve the tenant from the authenticated
and authorized principal, or validate the header against that principal before
storing the verified tenant ID in Context. Preserve the existing Context
propagation guidance while ensuring downstream controllers, jobs, and logging
receive only an authorized tenant value.
In @.github/skills/laravel-best-practices/rules/caching.md:
- Around line 64-70: Update the “Configure Failover Cache Stores in Production”
guidance to explicitly set failover as the default cache store, adding the
CACHE_STORE=failover environment setting or equivalent default configuration
alongside the failover store definition.
- Around line 35-37: Update the cache-tag support statement in the “Use Cache
Tags to Invalidate Related Groups” section to remove dynamodb from the listed
supported drivers, leaving only redis and memcached.
In @.github/skills/laravel-best-practices/rules/db-performance.md:
- Around line 152-168: Update the “Use cursor() for Memory-Efficient Iteration”
guidance to document that PDO may buffer the full result set even though
cursor() reduces hydrated-model memory. Recommend lazy() or chunk()/chunkById()
for truly large queries, while preserving cursor() for suitable read-only
iteration.
In @.github/skills/laravel-best-practices/rules/http-client.md:
- Around line 38-49: Update the Stripe retry example’s Http client chain to
include a stable Idempotency-Key header before posting the charge. Ensure the
same key is reused across retries, while preserving the existing retry, timeout,
and POST behavior.
In @.github/skills/laravel-best-practices/rules/queue-jobs.md:
- Around line 70-74: Update the failed method to handle a null $exception before
accessing its message. Use a nullsafe or conditional expression for the logged
error value while preserving the podcast status update and existing log context.
In @.github/skills/laravel-best-practices/rules/security.md:
- Around line 122-131: Correct the “Validate File Uploads” guidance to
accurately distinguish the rules: describe mimes as validating guessed MIME
types from file content, mimetypes as accepting explicit MIME strings, and
extensions as validating the user-supplied filename extension. Update the
surrounding wording without changing the example validation rule.
In @.github/skills/tailwindcss-development/SKILL.md:
- Line 3: Update the Tailwind guidance to distinguish v3 and v4 workflows
instead of presenting v4-only practices as universal. Revise the body sections
containing “Always use Tailwind CSS v4”, “@import "tailwindcss"”, and “@theme”
so v4 instructions apply only to v4 projects, while v3 projects retain
compatible configuration and utility guidance.
In `@opencode.json`:
- Around line 8-10: Update the MCP command configuration in opencode.json and
the corresponding .codex/config.toml entry to remove machine-specific WSL, PHP,
and project paths. Use portable command resolution and project-relative
invocation so Laravel Boost starts correctly across environments.
---
Minor comments:
In @.github/skills/configure-nightwatch/reference.md:
- Around line 42-47: Rename the “Disable sensitive data collection” section in
the Nightwatch configuration reference to accurately describe that it disables
request-payload capture and redacts selected headers, without implying that all
request metadata collection is disabled.
- Around line 3-15: Add `Scheduled Tasks` and `Logs` rows to the “Configuration
Summary by Event Type” table, documenting
`NIGHTWATCH_SCHEDULED_TASK_SAMPLE_RATE` and `NIGHTWATCH_LOG_LEVEL` in their
appropriate columns. Keep the existing event rows and table structure unchanged.
- Around line 71-80: Add NIGHTWATCH_ENABLED=true to the development verification
checklist alongside NIGHTWATCH_REQUEST_SAMPLE_RATE=1.0, so the checklist
explicitly enables Nightwatch collection during development.
In @.github/skills/configure-nightwatch/SKILL.md:
- Line 38: Update the fenced code block containing the ASCII flow diagram in
SKILL.md to specify the `text` language after the opening fence, preserving the
diagram content unchanged.
- Around line 60-72: Update the Global Sample Rates section in SKILL.md to list
NIGHTWATCH_SCHEDULED_TASK_SAMPLE_RATE as a separate environment variable for
scheduled Artisan tasks, including an appropriate default or recommendation
consistent with the surrounding sampling settings.
In @.github/skills/laravel-best-practices/rules/blade-views.md:
- Around line 25-32: Update the Blade view example associated with the
fragmentIf call to define a matching `@fragment`('user-list') block around the
user-list markup. Keep the full-page rendering intact while ensuring the named
fragment returned by fragmentIf is explicitly declared.
In @.github/skills/laravel-best-practices/rules/caching.md:
- Around line 21-27: Update the Cache::flexible() guidance in the
stale-while-revalidate section to describe cache refreshing as deferred
execution after the response, not as background processing. Adjust the
explanation and example annotation while preserving the existing fresh and stale
duration semantics.
In @.github/skills/laravel-best-practices/rules/events-notifications.md:
- Around line 3-5: Update the “Rely on Event Discovery” section to document that
Laravel discovers both handle(EventType $event) and __invoke(...) listener
methods, and clarify that discovery is limited to configured paths. State that
listeners outside those paths require withEvents(discover: [...]) or manual
registration.
In @.github/skills/laravel-best-practices/rules/http-client.md:
- Around line 111-119: Update the pooled response handling after Http::pool() so
each named response—users, posts, and comments—is checked for success before
calling json(). Use throw() or an equivalent successful() guard consistently for
every response, preserving the existing response aliases and parsing behavior.
In @.github/skills/laravel-best-practices/rules/queue-jobs.md:
- Around line 102-113: Remove the `$tries = 0` declaration and the accompanying
requirement from the `retryUntil()` guidance, leaving the example focused solely
on the time-based retry deadline and preserving the existing `retryUntil()`
implementation.
- Around line 3-5: Update the “Set retry_after Greater Than timeout” guidance in
queue-jobs.md to require a few seconds of buffer between retry_after and the job
timeout, rather than merely requiring retry_after to be longer. Preserve the
existing duplicate-execution warning and clearly state that the buffer accounts
for shutdown and scheduling overhead.
In @.github/skills/laravel-best-practices/rules/scheduling.md:
- Around line 11-13: Update the “Use runInBackground() for Concurrent Long
Tasks” guidance to state that runInBackground() applies only to schedules
created with command() or exec(). Remove the broader implication that it works
for all scheduler task types, while preserving the concurrency explanation.
In @.github/skills/laravel-best-practices/rules/security.md:
- Around line 91-94: Update the CSRF Protection guidance in security.md to
remove the claim that Inertia automatically applies the Blade `@csrf` directive.
State that `@csrf` applies only to Blade forms, while Inertia relies on the XSRF
cookie/header flow.
In @.github/skills/laravel-best-practices/rules/style.md:
- Around line 34-36: Revise the `first()->name` to `value('name')` guidance in
the style rule so it is not presented as a general replacement. Qualify that
`value()` returns the raw column value, while `first()->name` may apply Eloquent
accessors and casts, and preserve the recommendation only where raw-value
behavior is intended.
In @.github/skills/laravel-best-practices/rules/validation.md:
- Around line 60-70: Update the after() validation callback to handle a missing
product before comparing quantity against stock, using the existing Product
lookup; add the products.id existence validation or return early when
Product::find($this->product_id) is null, while preserving the
insufficient-stock error for existing products.
In `@composer.json`:
- Line 63: Update the laravel/boost Composer constraint from ^2.4 to ^2.4.12,
keeping the dependency pinned to that minimum patch release.
---
Nitpick comments:
In @.github/skills/configure-nightwatch/SKILL.md:
- Around line 321-331: Update the “Redact request payloads” section to
explicitly state that NIGHTWATCH_CAPTURE_REQUEST_PAYLOAD=true captures request
bodies only for exception events, not for all requests.
In @.github/skills/laravel-best-practices/rules/events-notifications.md:
- Around line 19-25: Revise the “Always Queue Notifications” guidance to
recommend queueing only notifications that perform slow or external work, while
allowing immediate or database-only notifications to remain synchronous when
appropriate. Update the InvoicePaid example and surrounding text to reflect this
conditional guidance, and note that queued notifications require a running
worker.
In @.github/skills/laravel-best-practices/SKILL.md:
- Around line 21-25: Update the Laravel best-practices guidance to require
identifying the project's declared Laravel version constraint before
recommending or applying version-sensitive APIs such as defer(), Context,
Concurrency, and #[CollectedBy]. Add explicit compatibility gates or version
checks for these examples, while preserving the existing instruction to verify
APIs against the installed framework.
In `@app-modules/integration-devto/docs/recipes/reactions-stats-scraper.js`:
- Around line 56-58: Update the reaction extraction logic around
informationElement so it returns null immediately when
detailsElement.children[0] is absent, matching extractReaction’s handling of
missing detailsElement and allowing extractReactions to filter the malformed
entry instead of assigning UNKNOWN_VALUE.
- Around line 96-113: Remove the unnecessary textarea.focus() call from
copyToClipboardFallback while preserving the existing select(), copy execution,
and cleanup behavior.
- Line 14: Add diagnostic logging around extractReactions so that when the
reactions container is found but zero entries are extracted, it emits a debug
message indicating the selector or extraction failure. Preserve the existing
extraction behavior and avoid logging when the container is absent or entries
were successfully found.
🪄 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: f81af6cf-0f56-410f-b0d7-2d0c7f1c81ec
⛔ Files ignored due to path filters (2)
composer.lockis excluded by!**/*.lockpackage-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (30)
.codex/config.toml.github/skills/configure-nightwatch/SKILL.md.github/skills/configure-nightwatch/reference.md.github/skills/fluxui-development/SKILL.md.github/skills/laravel-best-practices/SKILL.md.github/skills/laravel-best-practices/rules/advanced-queries.md.github/skills/laravel-best-practices/rules/architecture.md.github/skills/laravel-best-practices/rules/blade-views.md.github/skills/laravel-best-practices/rules/caching.md.github/skills/laravel-best-practices/rules/collections.md.github/skills/laravel-best-practices/rules/config.md.github/skills/laravel-best-practices/rules/db-performance.md.github/skills/laravel-best-practices/rules/eloquent.md.github/skills/laravel-best-practices/rules/error-handling.md.github/skills/laravel-best-practices/rules/events-notifications.md.github/skills/laravel-best-practices/rules/http-client.md.github/skills/laravel-best-practices/rules/mail.md.github/skills/laravel-best-practices/rules/migrations.md.github/skills/laravel-best-practices/rules/queue-jobs.md.github/skills/laravel-best-practices/rules/routing.md.github/skills/laravel-best-practices/rules/scheduling.md.github/skills/laravel-best-practices/rules/security.md.github/skills/laravel-best-practices/rules/style.md.github/skills/laravel-best-practices/rules/testing.md.github/skills/laravel-best-practices/rules/validation.md.github/skills/pest-testing/SKILL.md.github/skills/tailwindcss-development/SKILL.mdapp-modules/integration-devto/docs/recipes/reactions-stats-scraper.jscomposer.jsonopencode.json
| command = "wsl.exe" | ||
| args = ["/usr/bin/php8.5", "/home/sonse/heartdevs.com/artisan", "boost:mcp"] |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Repo files:\n'
git ls-files | sed -n '1,120p'
printf '\nTarget file:\n'
if git ls-files .codex/config.toml >/dev/null 2>&1; then
cat -n .codex/config.toml
else
echo '.codex/config.toml not tracked'
fi
printf '\nRelated references:\n'
rg -n --hidden --glob '!.git' --glob '!node_modules' --glob '!dist' --glob '!build' \
'boost:mcp|wsl\.exe|/home/sonse|artisan|working-directory|working_directory|cwd|mcp' \
. || trueRepository: he4rt/heartdevs.com
Length of output: 50376
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect any docs or config around Codex/MCP settings, if present.
fd -a 'README*|*.md|*.toml|*.json|*.yml|*.yaml' . \
| sed -n '1,120p'Repository: he4rt/heartdevs.com
Length of output: 484
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
p = Path('.codex/config.toml')
print('exists:', p.exists())
if p.exists():
print(p.read_text())
PYRepository: he4rt/heartdevs.com
Length of output: 296
Remove the machine-specific MCP path. .codex/config.toml hardcodes /home/sonse/heartdevs.com and php8.5, so the checked-in config only works on one WSL setup.
🤖 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 @.codex/config.toml around lines 2 - 3, Update the MCP command configuration
to remove the hardcoded machine-specific `/home/sonse/heartdevs.com` path and
`php8.5` executable, using the repository’s portable project and PHP invocation
mechanism instead. Preserve the existing `boost:mcp` command and argument
behavior while ensuring the checked-in configuration works across WSL setups.
| @@ -0,0 +1,81 @@ | |||
| --- | |||
| name: fluxui-development | |||
| description: "Use this skill for Flux UI development in Livewire applications only. Trigger when working with <flux:*> components, building or customizing Livewire component UIs, creating forms, modals, tables, or other interactive elements. Covers: flux: components (buttons, inputs, modals, forms, tables, date-pickers, kanban, badges, tooltips, etc.), component composition, Tailwind CSS styling, Heroicons/Lucide icon integration, validation patterns, responsive design, and theming. Do not use for non-Livewire frameworks or non-component styling." | |||
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== File outline =="
wc -l .github/skills/fluxui-development/SKILL.md
echo
echo "== Relevant lines =="
cat -n .github/skills/fluxui-development/SKILL.md | sed -n '1,40p'
echo
echo "== Search for free edition references =="
rg -n "free edition|pro|date picker|kanban|date-pickers" .github/skills/fluxui-development/SKILL.mdRepository: he4rt/heartdevs.com
Length of output: 3537
🌐 Web query:
Flux UI pricing date picker kanban pro free edition
💡 Result:
Flux UI is a component library specifically designed for Livewire applications [1][2]. It is structured into two main tiers: a free, open-source version and a paid Pro version [3]. The free version includes essential UI components such as buttons, dropdowns, and modals [4][5]. However, advanced features like the Date Picker and Kanban board are exclusively part of the paid Flux Pro tier [6][3]. Pricing for Flux Pro includes multiple license types [3]: - Solo License: Intended for individual developers, offering unlimited projects and one year of updates [3]. - Team License: Designed for teams, allowing unlimited developers and projects with one year of updates and priority email support [3]. Specific pricing structures may vary by plan; users are encouraged to visit the official pricing page at https://fluxui.dev/pricing to view the most current options and compare plan features [7][3]. After purchasing a Pro license, users can activate it within their application by running the command: php artisan flux:activate [1] This process requires the email address associated with the purchase and the provided license key [3][1].
Citations:
- 1: https://github.com/livewire/flux
- 2: https://livewire-flux.mintlify.app/introduction
- 3: https://livewire-flux.mintlify.app/concepts/pro-license
- 4: https://fluxui.dev/
- 5: https://v1.fluxui.dev/
- 6: https://livewire-flux.mintlify.app/pro/overview
- 7: https://fluxui.dev/pricing
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
p = Path('.github/skills/fluxui-development/SKILL.md')
text = p.read_text()
for needle in ["date pickers", "kanban", "free edition", "pro"]:
print(needle, "=>", needle in text)
PYRepository: he4rt/heartdevs.com
Length of output: 227
Remove Pro-only components from the free-edition skill. date-pickers and kanban belong in the Pro tier, but this file describes Flux UI free edition usage. Keep the coverage list aligned with the free components only, or label those items as Pro-only.
🤖 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 @.github/skills/fluxui-development/SKILL.md at line 3, Update the description
metadata for the Flux UI skill to remove date-pickers and kanban from the
free-edition coverage list, or explicitly mark both as Pro-only while keeping
the remaining component coverage unchanged.
| public function handle(array $data): Order | ||
| { | ||
| $order = Order::create($data); | ||
| $this->inventory->reserve($order); |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Wrap the order and reservation in an atomic workflow.
If inventory reservation fails, Order::create() has already persisted the order. Use DB::transaction() for database-backed work, or document an outbox/compensation flow for external inventory systems. (laravel.com)
🤖 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 @.github/skills/laravel-best-practices/rules/architecture.md around lines 12
- 15, Update the handle method’s order-creation and inventory-reservation
workflow to execute database-backed operations inside DB::transaction(),
ensuring a reservation failure rolls back the persisted order; if inventory is
external, document and implement an appropriate outbox or compensation flow
instead.
| // Or at query level | ||
| $product = Product::where('id', $id)->lockForUpdate()->first(); | ||
| ``` |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Place lockForUpdate() inside a transaction.
Without an enclosing transaction, the row lock can be released immediately after the select, leaving the subsequent operation unprotected. (laravel.com)
🤖 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 @.github/skills/laravel-best-practices/rules/architecture.md around lines 106
- 108, Update the query-level Product example using lockForUpdate() so the
select and subsequent operation execute inside an explicit database transaction.
Preserve the existing Product::where(...) lookup while demonstrating that the
lock remains active for the full transactional operation.
| $response = Http::post('https://api.stripe.com/v1/charges', $data); | ||
|
|
||
| if ($response->failed()) { | ||
| throw new PaymentFailedException('Charge failed'); | ||
| } | ||
| ``` | ||
|
|
||
| Correct: | ||
| ```php | ||
| $response = Http::retry([100, 500, 1000]) | ||
| ->timeout(10) | ||
| ->post('https://api.stripe.com/v1/charges', $data); |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Add an Idempotency-Key to the Stripe retry example. Retrying this POST without a stable idempotency key can create duplicate charges on transient failures.
🤖 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 @.github/skills/laravel-best-practices/rules/http-client.md around lines 38 -
49, Update the Stripe retry example’s Http client chain to include a stable
Idempotency-Key header before posting the charge. Ensure the same key is reused
across retries, while preserving the existing retry, timeout, and POST behavior.
| public function failed(?Throwable $exception): void | ||
| { | ||
| $this->podcast->update(['status' => 'failed']); | ||
| Log::error('Processing failed', ['id' => $this->podcast->id, 'error' => $exception->getMessage()]); | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the target file around the cited lines.
sed -n '1,140p' .github/skills/laravel-best-practices/rules/queue-jobs.md
# Search for nearby guidance about failed() or Throwable handling in the repo.
rg -n "failed\\(|\\?Throwable|getMessage\\(" .github/skills/laravel-best-practices/rules -SRepository: he4rt/heartdevs.com
Length of output: 3903
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Read only the relevant slice with line numbers.
nl -ba .github/skills/laravel-best-practices/rules/queue-jobs.md | sed -n '60,90p'Repository: he4rt/heartdevs.com
Length of output: 197
🏁 Script executed:
#!/bin/bash
set -euo pipefail
nl -ba .github/skills/laravel-best-practices/rules/queue-jobs.md | sed -n '60,90p'
rg -n "failed\\(|\\?Throwable|getMessage\\(" .github/skills/laravel-best-practices/rules -SRepository: he4rt/heartdevs.com
Length of output: 197
🌐 Web query:
Laravel queue failed method nullable Throwable exception getMessage failed(?Throwable $exception) docs
💡 Result:
In Laravel, the failed method on a queued job should define its exception parameter as nullable (e.g.,?Throwable $exception) [1]. When a job exceeds its maximum retry attempts or is manually failed without providing an exception, the framework may invoke the failed method with a null value [1]. If the parameter is type-hinted as only Throwable (without the nullable prefix), calling the method with a null value will result in a type error [1]. Therefore, when implementing the cleanup logic, your signature should be: public function failed(?Throwable $exception): void { // Logic to execute when the job fails... } As documented in the Laravel API [2] and evidenced by framework discussions [1], this pattern ensures compatibility with instances where no specific exception is available to be passed to the method.
Citations:
- 1: [10.x] Nullable
failedmethod laravel/docs#9445 - 2: https://api.laravel.com/docs/13.x/Illuminate/Queue/Jobs/RedisJob.html
Guard the nullable failure exception. failed(?Throwable $exception) may receive null; $exception->getMessage() will crash the handler. Use a nullsafe/conditional message.
🤖 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 @.github/skills/laravel-best-practices/rules/queue-jobs.md around lines 70 -
74, Update the failed method to handle a null $exception before accessing its
message. Use a nullsafe or conditional expression for the logged error value
while preserving the podcast status update and existing log context.
| ## Validate File Uploads | ||
|
|
||
| Validate extension, MIME type, and size. The `mimes` rule checks extensions; use `mimetypes` for actual MIME type validation. Never trust client-provided filenames. | ||
|
|
||
| ```php | ||
| public function rules(): array | ||
| { | ||
| return [ | ||
| 'avatar' => ['required', 'image', 'mimes:jpg,jpeg,png,webp', 'max:2048'], | ||
| ]; |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
git ls-files .github/skills/laravel-best-practices/rules/security.md
wc -l .github/skills/laravel-best-practices/rules/security.md
sed -n '110,140p' .github/skills/laravel-best-practices/rules/security.mdRepository: he4rt/heartdevs.com
Length of output: 1023
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import pathlib, re
p = pathlib.Path('.github/skills/laravel-best-practices/rules/security.md')
text = p.read_text()
for i, line in enumerate(text.splitlines(), 1):
if 118 <= i <= 136:
print(f"{i}:{line}")
PYRepository: he4rt/heartdevs.com
Length of output: 692
🌐 Web query:
Laravel validation mimes mimetypes extensions docs 12.x
💡 Result:
In Laravel 12.x, file validation is managed through three primary rules: mimes, mimetypes, and extensions, each serving a distinct purpose in verifying file integrity and metadata [1][2]. mimes:foo,bar,... The mimes rule validates the file's content by reading it to guess its MIME type and verifying that it matches one of the extensions provided [1][2]. For example, mimes:jpg,png will allow a file if its internal content corresponds to the MIME types associated with those extensions [1]. Importantly, this rule does not verify that the file's user-assigned extension matches the content; a file named photo.txt containing valid PNG data would be accepted [1][2]. mimetypes:text/plain,... The mimetypes rule validates the file's actual MIME type by reading its content [1][2]. Unlike mimes, you provide the MIME type string directly (e.g., mimetypes:image/jpeg,application/pdf) rather than file extensions [1][2]. extensions:foo,bar,... The extensions rule specifically validates the file's user-assigned extension [1][2]. Because mimes and mimetypes rules only inspect file content and ignore the filename extension, it is recommended to use the extensions rule in combination with them to ensure the file's extension matches your expected format [1][2]. Best Practices To ensure robust security and validation, you should never rely on user-assigned extensions alone [1][2]. It is best practice to combine these rules to verify both the file content and the filename extension: 'photo' => ['file', 'mimes:jpg,png', 'extensions:jpg,png'] Additionally, Laravel provides the Illuminate\Validation\Rules\File class, which offers a fluent interface for these validations [3][4]. You can chain these requirements easily: use Illuminate\Validation\Rules\File; Validator::validate($request->all, [ 'photo' => [ File::types(['jpg', 'png']) // Validates MIME type and extension ->max(1024), ], ]);
Citations:
- 1: https://v12.x.laravel.wiki/en/validation
- 2: https://laravel.com/docs/13.x/validation.md
- 3: https://github.com/laravel/framework/blob/12.x/src/Illuminate/Validation/Rules/File.php
- 4: https://api.laravel.com/docs/13.x/Illuminate/Validation/Rules/File.html
Fix the mimes / mimetypes descriptions. mimes checks the file’s guessed MIME type from content, mimetypes accepts MIME strings directly, and extensions is what validates the user-supplied filename extension.
🤖 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 @.github/skills/laravel-best-practices/rules/security.md around lines 122 -
131, Correct the “Validate File Uploads” guidance to accurately distinguish the
rules: describe mimes as validating guessed MIME types from file content,
mimetypes as accepting explicit MIME strings, and extensions as validating the
user-supplied filename extension. Update the surrounding wording without
changing the example validation rule.
| @@ -0,0 +1,119 @@ | |||
| --- | |||
| name: tailwindcss-development | |||
| description: "Always invoke when the user's message includes 'tailwind' in any form. Also invoke for: building responsive grid layouts (multi-column card grids, product grids), flex/grid page structures (dashboards with sidebars, fixed topbars, mobile-toggle navs), styling UI components (cards, tables, navbars, pricing sections, forms, inputs, badges), adding dark mode variants, fixing spacing or typography, and Tailwind v3/v4 work. The core use case: writing or fixing Tailwind utility classes in HTML templates (Blade, JSX, Vue). Skip for backend PHP logic, database queries, API routes, JavaScript with no HTML/CSS component, CSS file audits, build tool configuration, and vanilla CSS." | |||
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the relevant skill file with line numbers, keeping output small.
wc -l .github/skills/tailwindcss-development/SKILL.md
sed -n '1,120p' .github/skills/tailwindcss-development/SKILL.md | cat -nRepository: he4rt/heartdevs.com
Length of output: 4890
Split the v3 and v4 guidance. The description advertises Tailwind v3/v4 support, but the body is v4-only (Always use Tailwind CSS v4, @import "tailwindcss", @theme), which will send v3 projects down incompatible changes.
🤖 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 @.github/skills/tailwindcss-development/SKILL.md at line 3, Update the
Tailwind guidance to distinguish v3 and v4 workflows instead of presenting
v4-only practices as universal. Revise the body sections containing “Always use
Tailwind CSS v4”, “@import "tailwindcss"”, and “@theme” so v4 instructions apply
only to v4 projects, while v3 projects retain compatible configuration and
utility guidance.
…-service guidance
|
Lgtm |
|
Issue fechada pois foi movida pro repositório do mkt-ext |
Closes #181
Summary
Adds a browser console script to extract Reactions History from dev.to article stats pages. The script extracts reaction data (type, user, avatar, date) and outputs structured JSON.