@rashidee/co2 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +25449 -0
- package/drizzle/0000_remarkable_charles_xavier.sql +210 -0
- package/drizzle/0001_wise_wolf_cub.sql +13 -0
- package/drizzle/0002_secret_spyke.sql +16 -0
- package/drizzle/0003_workspace_config_singleton.sql +16 -0
- package/drizzle/0004_terminal_claim_v120.sql +11 -0
- package/drizzle/0005_brainstorm_v124.sql +10 -0
- package/drizzle/0006_project_v140.sql +6 -0
- package/drizzle/0007_prd_wizard_v124.sql +14 -0
- package/drizzle/0008_workflow_artifact_v126.sql +24 -0
- package/drizzle/0009_project_import_v150.sql +7 -0
- package/drizzle/0010_quality_v151.sql +3 -0
- package/drizzle/meta/0000_snapshot.json +1335 -0
- package/drizzle/meta/0001_snapshot.json +1416 -0
- package/drizzle/meta/0002_snapshot.json +1510 -0
- package/drizzle/meta/_journal.json +83 -0
- package/package.json +41 -0
- package/plugin/.claude-plugin/marketplace.json +36 -0
- package/plugin/.claude-plugin/plugin.json +22 -0
- package/plugin/README.md +625 -0
- package/plugin/SKILLS.md +350 -0
- package/plugin/co2.svg +5 -0
- package/plugin/commands/brainstorm-loop.md +129 -0
- package/plugin/skills/conductor-defect/SKILL.md +898 -0
- package/plugin/skills/conductor-feature-develop/SKILL.md +1383 -0
- package/plugin/skills/conductor-feature-develop/references/implementation-domain-template.md +131 -0
- package/plugin/skills/conductor-feature-develop/references/implementation-master-template.md +89 -0
- package/plugin/skills/conductor-feature-develop/references/playwright-setup.md +224 -0
- package/plugin/skills/conductor-feature-prepare/SKILL.md +604 -0
- package/plugin/skills/depgen-k8s/SKILL.md +468 -0
- package/plugin/skills/depgen-k8s/references/dockerfile-laravel.md +197 -0
- package/plugin/skills/depgen-k8s/references/dockerfile-nodejs.md +163 -0
- package/plugin/skills/depgen-k8s/references/dockerfile-spring-boot.md +174 -0
- package/plugin/skills/depgen-k8s/references/k8s-patterns.md +869 -0
- package/plugin/skills/mockgen-shadcn/SKILL.md +1067 -0
- package/plugin/skills/mockgen-shadcn/references/admin-layout-template.md +1467 -0
- package/plugin/skills/mockgen-shadcn/references/mockup-hub-template.md +498 -0
- package/plugin/skills/mockgen-shadcn/references/mockup-index-template.md +216 -0
- package/plugin/skills/mockgen-tailwind/SKILL.md +904 -0
- package/plugin/skills/mockgen-tailwind/references/admin-layout-template.md +720 -0
- package/plugin/skills/mockgen-tailwind/references/mockup-hub-template.md +498 -0
- package/plugin/skills/mockgen-tailwind/references/mockup-index-template.md +190 -0
- package/plugin/skills/modelgen-nosql/SKILL.md +617 -0
- package/plugin/skills/modelgen-nosql/references/model-extraction-methodology.md +497 -0
- package/plugin/skills/modelgen-nosql/references/nosql-design-guide.md +258 -0
- package/plugin/skills/modelgen-relational/SKILL.md +707 -0
- package/plugin/skills/modelgen-relational/references/model-extraction-methodology.md +499 -0
- package/plugin/skills/specgen-flutter-riverpod/SKILL.md +898 -0
- package/plugin/skills/specgen-flutter-riverpod/references/component-patterns.md +971 -0
- package/plugin/skills/specgen-flutter-riverpod/references/notification-patterns.md +457 -0
- package/plugin/skills/specgen-flutter-riverpod/references/routing-patterns.md +362 -0
- package/plugin/skills/specgen-flutter-riverpod/references/security-patterns.md +709 -0
- package/plugin/skills/specgen-flutter-riverpod/references/spec-template.md +1566 -0
- package/plugin/skills/specgen-flutter-riverpod/references/state-patterns.md +518 -0
- package/plugin/skills/specgen-flutter-riverpod/references/storage-patterns.md +370 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/SKILL.md +984 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/batch-patterns.md +359 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/messaging-patterns.md +468 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/modulith-patterns.md +461 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/reporting-patterns.md +803 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/security-patterns.md +501 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/spec-template.md +1268 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/web-patterns.md +301 -0
- package/plugin/skills/specgen-node-cli-web/SKILL.md +561 -0
- package/plugin/skills/specgen-node-cli-web/references/auth-patterns.md +293 -0
- package/plugin/skills/specgen-node-cli-web/references/cli-packaging-patterns.md +250 -0
- package/plugin/skills/specgen-node-cli-web/references/server-patterns.md +247 -0
- package/plugin/skills/specgen-node-cli-web/references/spec-template.md +401 -0
- package/plugin/skills/specgen-node-cli-web/references/testing-patterns.md +174 -0
- package/plugin/skills/specgen-react-mui/SKILL.md +789 -0
- package/plugin/skills/specgen-react-mui/references/component-patterns.md +1077 -0
- package/plugin/skills/specgen-react-mui/references/reporting-patterns.md +1998 -0
- package/plugin/skills/specgen-react-mui/references/routing-patterns.md +461 -0
- package/plugin/skills/specgen-react-mui/references/security-patterns.md +599 -0
- package/plugin/skills/specgen-react-mui/references/spec-template.md +1030 -0
- package/plugin/skills/specgen-react-mui/references/state-patterns.md +327 -0
- package/plugin/skills/specgen-react-tailwind/SKILL.md +859 -0
- package/plugin/skills/specgen-react-tailwind/references/component-patterns.md +1212 -0
- package/plugin/skills/specgen-react-tailwind/references/reporting-patterns.md +1529 -0
- package/plugin/skills/specgen-react-tailwind/references/routing-patterns.md +669 -0
- package/plugin/skills/specgen-react-tailwind/references/security-patterns.md +656 -0
- package/plugin/skills/specgen-react-tailwind/references/spec-template.md +1237 -0
- package/plugin/skills/specgen-react-tailwind/references/state-patterns.md +327 -0
- package/plugin/skills/specgen-sdk-java/SKILL.md +933 -0
- package/plugin/skills/specgen-sdk-java/references/api-extraction-patterns.md +247 -0
- package/plugin/skills/specgen-sdk-java/references/http-client-patterns.md +495 -0
- package/plugin/skills/specgen-sdk-java/references/packaging-patterns.md +366 -0
- package/plugin/skills/specgen-sdk-java/references/spec-template.md +956 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/SKILL.md +1284 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/batch-patterns.md +1224 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/jasper-patterns.md +1638 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/messaging-patterns.md +512 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/modulith-patterns.md +354 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/security-patterns.md +551 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/spec-template.md +2502 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/web-patterns.md +503 -0
- package/plugin/skills/specgen-spring-jpa-restapi/SKILL.md +990 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/batch-patterns.md +1224 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/messaging-patterns.md +512 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/modulith-patterns.md +279 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/reporting-patterns.md +1536 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/restapi-patterns.md +722 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/security-patterns.md +351 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/spec-template.md +553 -0
- package/plugin/skills/specgen-ts-cli/SKILL.md +861 -0
- package/plugin/skills/specgen-ts-cli/references/async-patterns.md +1101 -0
- package/plugin/skills/specgen-ts-cli/references/command-patterns.md +383 -0
- package/plugin/skills/specgen-ts-cli/references/config-patterns.md +430 -0
- package/plugin/skills/specgen-ts-cli/references/database-patterns.md +750 -0
- package/plugin/skills/specgen-ts-cli/references/packaging-patterns.md +426 -0
- package/plugin/skills/specgen-ts-cli/references/spec-template.md +1391 -0
- package/plugin/skills/specgen-ts-cli/references/testing-patterns.md +909 -0
- package/plugin/skills/testgen-functional/SKILL.md +1381 -0
- package/plugin/skills/tracegen-matrix/SKILL.md +243 -0
- package/plugin/skills/util-preparek8senv/SKILL.md +422 -0
- package/plugin/skills/util-projectinit/SKILL.md +307 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-loop.md +129 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-protocol.md +144 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-setup-guide.md +153 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-template-appdev.md +87 -0
- package/plugin/skills/util-projectinit/reference/co2-context-generation-guide.md +761 -0
- package/plugin/skills/util-projectsync/SKILL.md +501 -0
- package/plugin/skills/util-updprd/SKILL.md +324 -0
- package/plugin/skills/util-usanalyzer/SKILL.md +307 -0
- package/plugin/skills/util-ustagger/SKILL.md +154 -0
- package/static/assets/abnfDiagram-VRR7QNED-DvPuwyCV.js +1 -0
- package/static/assets/arc-DRKw7sjs.js +1 -0
- package/static/assets/architectureDiagram-ZJ3FMSHR-CaNcxUbC.js +36 -0
- package/static/assets/blockDiagram-677ZJIJ3-Demd4AOK.js +132 -0
- package/static/assets/c4Diagram-LMCZKHZV-PVKUfc2x.js +10 -0
- package/static/assets/channel-C2nVbuwv.js +1 -0
- package/static/assets/chunk-2Q5K7J3B-CExf8ww_.js +1 -0
- package/static/assets/chunk-32BRIVSS-CFPaoONF.js +1 -0
- package/static/assets/chunk-5VM5RSS4-DE2esM67.js +15 -0
- package/static/assets/chunk-EX3LRPZG-SON_YdDG.js +231 -0
- package/static/assets/chunk-JWPE2WC7-Qxah8LNr.js +1 -0
- package/static/assets/chunk-MOJQB5TN-BcWGQV3j.js +88 -0
- package/static/assets/chunk-RYQCIY6F-DkDj-OR5.js +1 -0
- package/static/assets/chunk-V7JOEXUC-BlI1Mrah.js +206 -0
- package/static/assets/chunk-VR4S4FIN-Agf__duj.js +1 -0
- package/static/assets/chunk-XXDRQBXY-B5CfAh85.js +1 -0
- package/static/assets/classDiagram-OUVF2IWQ-DXJIljsR.js +1 -0
- package/static/assets/classDiagram-v2-EOCWNBFH-DXJIljsR.js +1 -0
- package/static/assets/cose-bilkent-JH36ORCC-DO0cQkcy.js +1 -0
- package/static/assets/cynefin-VYW2F7L2-CfOnsnXc.js +178 -0
- package/static/assets/cynefinDiagram-TSTJHNR4-BJ8tULAv.js +62 -0
- package/static/assets/cytoscape.esm-DTSO7Bv0.js +331 -0
- package/static/assets/dagre-VKFMJZFB-DfjwzHqP.js +4 -0
- package/static/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/static/assets/diagram-FQU43EPY-CndSOIIM.js +3 -0
- package/static/assets/diagram-G47NLZAW-Czf5hN0Z.js +24 -0
- package/static/assets/diagram-NH7WQ7WH-COAyojGh.js +24 -0
- package/static/assets/diagram-OA4YK3LP-H8PoiN2m.js +30 -0
- package/static/assets/diagram-WEI45ONY-DzcaVzjp.js +41 -0
- package/static/assets/ebnfDiagram-CCIWWBDH-DPazGYLJ.js +1 -0
- package/static/assets/erDiagram-Q63AITRT-Bo-fubgF.js +85 -0
- package/static/assets/flowDiagram-23GEKE2U-CSvxUDwh.js +156 -0
- package/static/assets/ganttDiagram-NO4QXBWP-DnBveWX6.js +292 -0
- package/static/assets/gitGraphDiagram-IHSO6WYX-B3rVL8c-.js +106 -0
- package/static/assets/graph-C9eacEi8.js +1 -0
- package/static/assets/index-LZSQkLE2.css +41 -0
- package/static/assets/index-y7XDSgMG.js +495 -0
- package/static/assets/infoDiagram-FWYZ7A6U-CvWV9yy2.js +2 -0
- package/static/assets/init-Gi6I4Gst.js +1 -0
- package/static/assets/ishikawaDiagram-FXEZZL3T-DF28a1N6.js +70 -0
- package/static/assets/journeyDiagram-5HDEW3XC-CB6CugYk.js +139 -0
- package/static/assets/kanban-definition-HUTT4EX6-ResSLF6d.js +89 -0
- package/static/assets/katex-C5jXJg4s.js +257 -0
- package/static/assets/layout-DEXfKzaS.js +1 -0
- package/static/assets/linear-CLO--ryk.js +1 -0
- package/static/assets/map-Czzmt4hB.js +1 -0
- package/static/assets/mindmap-definition-LN4V7U3C-BvW3EbxX.js +96 -0
- package/static/assets/ordinal-Cboi1Yqb.js +1 -0
- package/static/assets/pegDiagram-2B236MQR-BHCgqrrM.js +1 -0
- package/static/assets/pieDiagram-ENE6RG2P-DVmCQ5FA.js +39 -0
- package/static/assets/quadrantDiagram-ABIIQ3AL-B3e5KR52.js +7 -0
- package/static/assets/railroadDiagram-RFXS5EU6-Csv5ysLc.js +1 -0
- package/static/assets/requirementDiagram-TGXJPOKE-DOMVzvnB.js +84 -0
- package/static/assets/sankeyDiagram-HTMAVEWB-B1dcTOvy.js +40 -0
- package/static/assets/sequenceDiagram-DBY2YBRQ-BY414yeO.js +162 -0
- package/static/assets/sizeCapture-X5ZJPWSS-CuJfrfBN.js +1 -0
- package/static/assets/stateDiagram-2N3HPSRC-FX4rJkzV.js +1 -0
- package/static/assets/stateDiagram-v2-6OUMAXLB-BVufbO_H.js +1 -0
- package/static/assets/swimlanes-5IMT3BWC-Sfy58mmv.js +2 -0
- package/static/assets/swimlanesDiagram-G3AALYLV-wDCDw08H.js +8 -0
- package/static/assets/timeline-definition-FHXFAJF6-CmV7by8p.js +120 -0
- package/static/assets/vennDiagram-L72KCM5P-FqIyFZFt.js +34 -0
- package/static/assets/wardleyDiagram-EHGQE667-BZ06O45i.js +78 -0
- package/static/assets/xychartDiagram-FW5EYKEG-BOkffR06.js +7 -0
- package/static/index.html +24 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
# Scheduling Patterns — Laravel Task Scheduling + Queue Batching
|
|
2
|
+
|
|
3
|
+
This reference describes the scheduling and batch processing scaffolding for the spec.
|
|
4
|
+
Include this content in Section 18 of the generated specification. All code samples must
|
|
5
|
+
be reproduced in the generated spec with full use statements and constructor injection.
|
|
6
|
+
|
|
7
|
+
The scheduling feature has two tiers:
|
|
8
|
+
- **Scheduling = yes**: Laravel Task Scheduling for cron-triggered jobs (always included)
|
|
9
|
+
- **Scheduling = yes AND Batch Processing = yes**: Adds `Bus::batch()` for chunk-oriented
|
|
10
|
+
data processing triggered by scheduled commands
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Architecture Overview
|
|
15
|
+
|
|
16
|
+
### Scheduling-Only Mode (Scheduling = yes, Batch Processing = no)
|
|
17
|
+
|
|
18
|
+
When batch processing is not selected, Laravel Task Scheduling runs standalone. Scheduled
|
|
19
|
+
commands execute application logic directly (service calls, API calls, cleanup tasks, etc.)
|
|
20
|
+
without the batch pipeline.
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
Laravel Scheduler (cron: * * * * * php artisan schedule:run)
|
|
24
|
+
└── Scheduled Command (daily at 02:00)
|
|
25
|
+
└── executes business logic directly (service calls, etc.)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Scheduling + Batch Mode (Scheduling = yes, Batch Processing = yes)
|
|
29
|
+
|
|
30
|
+
When batch processing is selected, scheduled commands dispatch job batches. This gives
|
|
31
|
+
the application cron-based scheduling with robust, restartable, chunk-oriented processing.
|
|
32
|
+
|
|
33
|
+
- **Laravel Scheduler**: Manages job scheduling — cron triggers, intervals.
|
|
34
|
+
The scheduler decides WHEN jobs run.
|
|
35
|
+
- **Bus::batch()**: Manages job execution — processing data in chunks with
|
|
36
|
+
progress tracking, failure handling, and cancellation support.
|
|
37
|
+
Batching decides HOW jobs run.
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
Laravel Scheduler (cron: * * * * *)
|
|
41
|
+
└── Scheduled Command (daily at 02:00)
|
|
42
|
+
└── Bus::batch([...chunk jobs...])
|
|
43
|
+
├── ProcessChunkJob (items 1-1000)
|
|
44
|
+
├── ProcessChunkJob (items 1001-2000)
|
|
45
|
+
└── ProcessChunkJob (items 2001-3000)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Composer Dependencies
|
|
51
|
+
|
|
52
|
+
No additional packages needed — scheduling and batching are built into Laravel:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"require": {
|
|
57
|
+
"laravel/framework": "^12.0"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
For batch processing, ensure the batch tables migration exists:
|
|
63
|
+
```bash
|
|
64
|
+
php artisan make:queue-batches-table
|
|
65
|
+
php artisan migrate
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Application Configuration
|
|
71
|
+
|
|
72
|
+
### Scheduling Configuration
|
|
73
|
+
|
|
74
|
+
```php
|
|
75
|
+
// routes/console.php (Laravel 11+)
|
|
76
|
+
use Illuminate\Support\Facades\Schedule;
|
|
77
|
+
|
|
78
|
+
// Scheduling-only jobs
|
|
79
|
+
Schedule::command('app:cleanup-expired-records')
|
|
80
|
+
->dailyAt('02:00')
|
|
81
|
+
->withoutOverlapping()
|
|
82
|
+
->onOneServer()
|
|
83
|
+
->appendOutputTo(storage_path('logs/scheduler.log'));
|
|
84
|
+
|
|
85
|
+
// [If Batch Processing = yes] Batch-triggered jobs
|
|
86
|
+
Schedule::command('app:process-data-export')
|
|
87
|
+
->dailyAt('03:00')
|
|
88
|
+
->withoutOverlapping()
|
|
89
|
+
->onOneServer();
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Queue Configuration (for batching)
|
|
93
|
+
|
|
94
|
+
```php
|
|
95
|
+
// config/queue.php
|
|
96
|
+
'connections' => [
|
|
97
|
+
'database' => [
|
|
98
|
+
'driver' => 'database',
|
|
99
|
+
'table' => 'jobs',
|
|
100
|
+
'queue' => 'default',
|
|
101
|
+
'retry_after' => 90,
|
|
102
|
+
'after_commit' => true,
|
|
103
|
+
],
|
|
104
|
+
|
|
105
|
+
// [If Messaging = yes] RabbitMQ connection
|
|
106
|
+
'rabbitmq' => [
|
|
107
|
+
'driver' => 'rabbitmq',
|
|
108
|
+
'queue' => env('RABBITMQ_QUEUE', 'default'),
|
|
109
|
+
'connection' => PhpAmqpLib\Connection\AMQPLazyConnection::class,
|
|
110
|
+
'hosts' => [
|
|
111
|
+
[
|
|
112
|
+
'host' => env('RABBITMQ_HOST', '127.0.0.1'),
|
|
113
|
+
'port' => env('RABBITMQ_PORT', 5672),
|
|
114
|
+
'user' => env('RABBITMQ_USER', 'guest'),
|
|
115
|
+
'password' => env('RABBITMQ_PASSWORD', 'guest'),
|
|
116
|
+
'vhost' => env('RABBITMQ_VHOST', '/'),
|
|
117
|
+
],
|
|
118
|
+
],
|
|
119
|
+
],
|
|
120
|
+
],
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Package Structure
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
app/
|
|
129
|
+
├── Console/
|
|
130
|
+
│ └── Commands/
|
|
131
|
+
│ ├── CleanupExpiredRecordsCommand.php # Direct scheduled command
|
|
132
|
+
│ └── [If Batch] ProcessDataExportCommand.php # Batch-dispatching command
|
|
133
|
+
├── Jobs/
|
|
134
|
+
│ ├── [If Batch] ProcessExportChunkJob.php # Chunk processing job
|
|
135
|
+
│ └── [If Batch] ExportCompletionJob.php # Post-batch cleanup
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Scheduling-Only Mode
|
|
141
|
+
|
|
142
|
+
### Scheduled Command (Direct Execution)
|
|
143
|
+
|
|
144
|
+
```php
|
|
145
|
+
namespace App\Console\Commands;
|
|
146
|
+
|
|
147
|
+
use Illuminate\Console\Command;
|
|
148
|
+
use Modules\Order\Contracts\OrderServiceInterface;
|
|
149
|
+
|
|
150
|
+
class CleanupExpiredRecordsCommand extends Command
|
|
151
|
+
{
|
|
152
|
+
protected $signature = 'app:cleanup-expired-records';
|
|
153
|
+
protected $description = 'Delete records older than the configured retention period';
|
|
154
|
+
|
|
155
|
+
public function __construct(
|
|
156
|
+
private readonly OrderServiceInterface $orderService,
|
|
157
|
+
) {
|
|
158
|
+
parent::__construct();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
public function handle(): int
|
|
162
|
+
{
|
|
163
|
+
$this->info('Starting cleanup of expired records...');
|
|
164
|
+
|
|
165
|
+
$deleted = $this->orderService->deleteExpiredRecords(
|
|
166
|
+
olderThanDays: config('app.retention_days', 30)
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
$this->info("Deleted {$deleted} expired records.");
|
|
170
|
+
|
|
171
|
+
return self::SUCCESS;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Scheduling + Batch Mode
|
|
179
|
+
|
|
180
|
+
### Batch-Dispatching Command
|
|
181
|
+
|
|
182
|
+
```php
|
|
183
|
+
namespace App\Console\Commands;
|
|
184
|
+
|
|
185
|
+
use App\Jobs\ProcessExportChunkJob;
|
|
186
|
+
use Illuminate\Bus\Batch;
|
|
187
|
+
use Illuminate\Console\Command;
|
|
188
|
+
use Illuminate\Support\Facades\Bus;
|
|
189
|
+
use Modules\Order\Contracts\OrderServiceInterface;
|
|
190
|
+
use Throwable;
|
|
191
|
+
|
|
192
|
+
class ProcessDataExportCommand extends Command
|
|
193
|
+
{
|
|
194
|
+
protected $signature = 'app:process-data-export';
|
|
195
|
+
protected $description = 'Export order data in batched chunks';
|
|
196
|
+
|
|
197
|
+
public function __construct(
|
|
198
|
+
private readonly OrderServiceInterface $orderService,
|
|
199
|
+
) {
|
|
200
|
+
parent::__construct();
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
public function handle(): int
|
|
204
|
+
{
|
|
205
|
+
$this->info('Preparing data export batch...');
|
|
206
|
+
|
|
207
|
+
$totalRecords = $this->orderService->countExportable();
|
|
208
|
+
$chunkSize = 1000;
|
|
209
|
+
$jobs = [];
|
|
210
|
+
|
|
211
|
+
for ($offset = 0; $offset < $totalRecords; $offset += $chunkSize) {
|
|
212
|
+
$jobs[] = new ProcessExportChunkJob(
|
|
213
|
+
offset: $offset,
|
|
214
|
+
limit: $chunkSize,
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (empty($jobs)) {
|
|
219
|
+
$this->info('No records to export.');
|
|
220
|
+
return self::SUCCESS;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
$batch = Bus::batch($jobs)
|
|
224
|
+
->then(function (Batch $batch) {
|
|
225
|
+
logger()->info("Export batch {$batch->id} completed successfully.");
|
|
226
|
+
})
|
|
227
|
+
->catch(function (Batch $batch, Throwable $e) {
|
|
228
|
+
logger()->error("Export batch {$batch->id} failed: {$e->getMessage()}");
|
|
229
|
+
})
|
|
230
|
+
->finally(function (Batch $batch) {
|
|
231
|
+
logger()->info("Export batch {$batch->id} finished. " .
|
|
232
|
+
"Processed: {$batch->processedJobs()}, Failed: {$batch->failedJobs}");
|
|
233
|
+
})
|
|
234
|
+
->name('data-export-' . now()->format('Y-m-d'))
|
|
235
|
+
->allowFailures()
|
|
236
|
+
->dispatch();
|
|
237
|
+
|
|
238
|
+
$this->info("Dispatched batch {$batch->id} with " . count($jobs) . " jobs.");
|
|
239
|
+
|
|
240
|
+
return self::SUCCESS;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Chunk Processing Job
|
|
246
|
+
|
|
247
|
+
```php
|
|
248
|
+
namespace App\Jobs;
|
|
249
|
+
|
|
250
|
+
use Illuminate\Bus\Batchable;
|
|
251
|
+
use Illuminate\Bus\Queueable;
|
|
252
|
+
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
253
|
+
use Illuminate\Foundation\Bus\Dispatchable;
|
|
254
|
+
use Illuminate\Queue\InteractsWithQueue;
|
|
255
|
+
use Illuminate\Queue\SerializesModels;
|
|
256
|
+
use Modules\Order\Contracts\OrderServiceInterface;
|
|
257
|
+
|
|
258
|
+
class ProcessExportChunkJob implements ShouldQueue
|
|
259
|
+
{
|
|
260
|
+
use Batchable, Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
|
261
|
+
|
|
262
|
+
public int $tries = 3;
|
|
263
|
+
public int $backoff = 60;
|
|
264
|
+
|
|
265
|
+
public function __construct(
|
|
266
|
+
public readonly int $offset,
|
|
267
|
+
public readonly int $limit,
|
|
268
|
+
) {}
|
|
269
|
+
|
|
270
|
+
public function handle(OrderServiceInterface $orderService): void
|
|
271
|
+
{
|
|
272
|
+
if ($this->batch()?->cancelled()) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
$records = $orderService->getExportableChunk($this->offset, $this->limit);
|
|
277
|
+
|
|
278
|
+
foreach ($records as $record) {
|
|
279
|
+
// Process each record (transform, export, etc.)
|
|
280
|
+
$orderService->markAsExported($record->id);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
logger()->info("Processed export chunk: offset={$this->offset}, count=" . count($records));
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Monitoring Batches
|
|
291
|
+
|
|
292
|
+
Laravel provides built-in batch monitoring:
|
|
293
|
+
|
|
294
|
+
```php
|
|
295
|
+
// Check batch progress
|
|
296
|
+
$batch = Bus::findBatch($batchId);
|
|
297
|
+
echo "Progress: {$batch->progress()}%";
|
|
298
|
+
echo "Pending: {$batch->pendingJobs}";
|
|
299
|
+
echo "Failed: {$batch->failedJobs}";
|
|
300
|
+
echo "Finished: " . ($batch->finished() ? 'yes' : 'no');
|
|
301
|
+
|
|
302
|
+
// Cancel a running batch
|
|
303
|
+
$batch->cancel();
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
For a dashboard view, query the `job_batches` table:
|
|
307
|
+
```php
|
|
308
|
+
$batches = DB::table('job_batches')
|
|
309
|
+
->orderByDesc('created_at')
|
|
310
|
+
->paginate(20);
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## Retry and Error Handling
|
|
316
|
+
|
|
317
|
+
### Job-level retry configuration
|
|
318
|
+
|
|
319
|
+
```php
|
|
320
|
+
class ProcessExportChunkJob implements ShouldQueue
|
|
321
|
+
{
|
|
322
|
+
public int $tries = 3; // Max retry attempts
|
|
323
|
+
public int $backoff = 60; // Seconds between retries
|
|
324
|
+
public int $timeout = 300; // Max execution time in seconds
|
|
325
|
+
public int $maxExceptions = 2; // Max exceptions before marking failed
|
|
326
|
+
|
|
327
|
+
public function failed(Throwable $exception): void
|
|
328
|
+
{
|
|
329
|
+
logger()->error("Export chunk failed permanently: {$exception->getMessage()}", [
|
|
330
|
+
'offset' => $this->offset,
|
|
331
|
+
'limit' => $this->limit,
|
|
332
|
+
]);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Failed jobs
|
|
338
|
+
|
|
339
|
+
Failed jobs are stored in the `failed_jobs` table. Retry or delete them:
|
|
340
|
+
```bash
|
|
341
|
+
php artisan queue:retry <job-id>
|
|
342
|
+
php artisan queue:retry --queue=default
|
|
343
|
+
php artisan queue:flush
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## Cron Setup
|
|
349
|
+
|
|
350
|
+
The Laravel scheduler requires a single cron entry on the server:
|
|
351
|
+
|
|
352
|
+
```cron
|
|
353
|
+
* * * * * cd /path-to-project && php artisan schedule:run >> /dev/null 2>&1
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
In Docker/production, use `schedule:work` for foreground scheduling:
|
|
357
|
+
```bash
|
|
358
|
+
php artisan schedule:work
|
|
359
|
+
```
|