← Back to list

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
- Actions represent a single user intent (example:
LogHealth,CreateBook,ResetWorkData). - Keep inputs minimal and explicit. Use descriptive parameter names.
- Decide whether the Action returns a model, a scalar, or nothing (
void).
Step 2: Create the Action class
- Use Artisan to create the class:
php artisan make:class Actions/ActionName --no-interaction
- Use
declare(strict_types=1);and theApp\Actionsnamespace. - Default to
final readonly classwith constructor property promotion. - If the Action must store a result (ex:
$this->book), keep itfinalbut notreadonly, and declare a private property for the result. - Always include explicit return types.
Step 3: Implement the action flow
- Typical flow:
- validate input
- perform data changes
- log user action
- update last activity date
- refresh content presence (when journal entry content changes)
- Validate ownership with
ModelNotFoundExceptionwhen a user does not own a journal or entry. - Validate input with
ValidationException::withMessages([...])when values are invalid. - Sanitize user-provided text with
TextSanitizer::plainText(). - Use Eloquent models and relationships. Avoid
DB::. - Queue background work on the
lowqueue:
LogUserAction::dispatch(...)->onQueue('low');
UpdateUserLastActivityDate::dispatch($user)->onQueue('low');
CheckPresenceOfContentInJournalEntry::dispatch($entry)->onQueue('low');
- If the Action mutates a journal entry module, reload the relationship before returning:
$this->entry->load('moduleHealth');
Step 4: Add tests
- Create
tests/Unit/Actions/ActionNameTest.php. - Use
RefreshDatabaseandQueue::fake(). - Use factories with explicit foreign keys. Never use
for()on factories. - Cover:
- happy path
- invalid input (throws
ValidationException) - unauthorized access (throws
ModelNotFoundException) - queued jobs on
lowqueue
Step 5: Run tests and lint
- Run the smallest relevant test file:
php artisan test tests/Unit/Actions/ActionNameTest.php
- Run
composer journalos:unit. - 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


