Back to list
djaiss

action-writer

by djaiss

JournalOS is a privacy-first, self-hosted personal journaling system with modular daily tracking (sleep, mood, work, health, and more).

1🍴 0📅 Jan 22, 2026

SKILL.md


name: action-writer description: Create or update an Action in app/Actions following JournalOS conventions (validation, logging, queues, tests).

Action Writer

This Skill helps you add or update an Action in app/Actions using the project conventions.

When to use this Skill

Use this Skill when:

  • Creating a new Action
  • Updating an existing Action

Instructions

Quick start

  • Pick the action name (verb-first) and its input/output types.
  • Create the Action class and implement execute().
  • Add or update unit tests in tests/Unit/Actions.
  • Run the smallest relevant test(s), then composer journalos:unit.

Step 1: Choose the action name and scope

  1. Actions represent a single user intent (example: LogHealth, CreateBook, ResetWorkData).
  2. Keep inputs minimal and explicit. Use descriptive parameter names.
  3. Decide whether the Action returns a model, a scalar, or nothing (void).

Step 2: Create the Action class

  1. Use Artisan to create the class:
php artisan make:class Actions/ActionName --no-interaction
  1. Use declare(strict_types=1); and the App\Actions namespace.
  2. Default to final readonly class with constructor property promotion.
  3. If the Action must store a result (ex: $this->book), keep it final but not readonly, and declare a private property for the result.
  4. Always include explicit return types.

Step 3: Implement the action flow

  1. Typical flow:
    • validate input
    • perform data changes
    • log user action
    • update last activity date
    • refresh content presence (when journal entry content changes)
  2. Validate ownership with ModelNotFoundException when a user does not own a journal or entry.
  3. Validate input with ValidationException::withMessages([...]) when values are invalid.
  4. Sanitize user-provided text with TextSanitizer::plainText().
  5. Use Eloquent models and relationships. Avoid DB::.
  6. Queue background work on the low queue:
LogUserAction::dispatch(...)->onQueue('low');
UpdateUserLastActivityDate::dispatch($user)->onQueue('low');
CheckPresenceOfContentInJournalEntry::dispatch($entry)->onQueue('low');
  1. If the Action mutates a journal entry module, reload the relationship before returning:
$this->entry->load('moduleHealth');

Step 4: Add tests

  1. Create tests/Unit/Actions/ActionNameTest.php.
  2. Use RefreshDatabase and Queue::fake().
  3. Use factories with explicit foreign keys. Never use for() on factories.
  4. Cover:
    • happy path
    • invalid input (throws ValidationException)
    • unauthorized access (throws ModelNotFoundException)
    • queued jobs on low queue

Step 5: Run tests and lint

  1. Run the smallest relevant test file:
php artisan test tests/Unit/Actions/ActionNameTest.php
  1. Run composer journalos:unit.
  2. Run Pint:
vendor/bin/pint --dirty

Score

Total Score

75/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

+10
人気

GitHub Stars 100以上

0/15
最近の活動

1ヶ月以内に更新

+10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

Reviews

💬

Reviews coming soon