Files
BarangaySystem/.claude/plans/c9f6ceb438a078dca529b327a64ffda9-complete.md
2026-06-06 18:43:00 +08:00

174 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
task: Seed real agricultural demo products, create a named demo store, assign products to the store, and set up a POS access key — all via the performance seeder API so no server-side code changes are needed
cycles: 3
context: true
private: false
started: 2026-05-16T00:00:00Z
finished: 2026-05-16T00:04:00Z
---
## files
- `app/Http/Controllers/Market/PerformanceController.php` — seeder endpoints already exist; use these instead of writing new code
- `routes/api.php` — perf endpoints: `POST /api/perf/seed/stores`, `POST /api/perf/seed/products`, `POST /api/perf/pos/simulate`
- `.env` — needs `PERF_API_TOKEN` and `PERF_ACTOR_HASH` set (check if already configured)
- `resources/js/Pages/ManageProductsAdmin.vue` — can verify products after seed
- `resources/js/Pages/PosMain.vue` — target for POS demo verification
## steps
### Step 0 — Verify perf API is enabled
1. Check `.env` for `PERF_API_TOKEN` and `PERF_ACTOR_HASH`. If missing:
- Set `PERF_API_TOKEN=bukid-demo-seed-2026` in `.env`
- Set `PERF_ACTOR_HASH` to the hashkey of the ULTIMATE user account (query: `SELECT hashkey FROM users WHERE acct_type='ULTIMATE' LIMIT 1` via UltimateConsole or direct DB)
2. Test with: `curl -s -H "X-Perf-Token: bukid-demo-seed-2026" http://localhost:9522/api/perf/ping`
- Expect `{"ok":true}`. If 403, token mismatch. If connection refused, server is down (task must wait for server).
### Step 1 — Create a demo store owner account (if the `099` store owner account doesn't own any store yet)
- Via the app UI or via Ultimate console SQL: confirm the store owner `099` (mobile) has a store. If not, proceed to create one.
### Step 2 — Create the demo store via perf API
```bash
curl -s -X POST http://localhost:9522/api/perf/seed/stores \
-H "Content-Type: application/json" \
-H "X-Perf-Token: bukid-demo-seed-2026" \
-d '{
"count": 1,
"owner_hash": "<STORE_OWNER_099_HASHKEY>",
"category": "Agri-Market",
"prefix": "BukidBounty Fresh Market"
}'
```
Note the returned store hashkey as `DEMO_STORE_HASH`.
### Step 3 — Seed 25 real agricultural products via perf API
```bash
curl -s -X POST http://localhost:9522/api/perf/seed/products \
-H "Content-Type: application/json" \
-H "X-Perf-Token: bukid-demo-seed-2026" \
-d '{
"count": 25,
"target_store_hash": "<DEMO_STORE_HASH>",
"attach_to_store": true,
"prefix": ""
}'
```
**However**, the perf seeder creates synthetic product names like "Product-0001". For demo quality, the products need realistic agricultural names. Therefore, instead of the perf seeder for products, **write a standalone Node.js or PHP artisan seed script** that creates the following 25 products directly via the app's own API endpoints (POST `/Products/Admin/New/` and `POST /Products/AssignToStore/`):
**Product list (agricultural, Bukidnon/Philippines context):**
1. Organic White Rice (25kg sack) — ₱1,200 — unit: sack
2. Organic Brown Rice (5kg) — ₱280 — unit: kg
3. White Corn Grits — ₱85 — unit: kg
4. Yellow Corn (fresh ears) — ₱35 — unit: piece
5. Fresh Kangkong (Water Spinach) — ₱25 — unit: bundle
6. Pechay (Bok Choy) — ₱30 — unit: bundle
7. Ampalaya (Bitter Gourd) — ₱60 — unit: kg
8. Sitaw (String Beans) — ₱55 — unit: bundle
9. Kamote (Sweet Potato) — ₱40 — unit: kg
10. Gabi (Taro Root) — ₱50 — unit: kg
11. Sayote (Chayote) — ₱45 — unit: kg
12. Labanos (Radish) — ₱30 — unit: bundle
13. Fresh Tomatoes — ₱70 — unit: kg
14. Carabao Mango (green) — ₱90 — unit: kg
15. Banana (Latundan) — ₱65 — unit: hand
16. Pineapple (Bukidnon) — ₱80 — unit: piece
17. Native Chicken (live) — ₱350 — unit: piece
18. Free-range Eggs — ₱12 — unit: piece
19. Fresh Tilapia — ₱130 — unit: kg
20. Bangus (Milkfish) — ₱180 — unit: kg
21. Carabao Milk (1L) — ₱120 — unit: liter
22. Coconut Oil (Virgin, 1L) — ₱250 — unit: bottle
23. Organic Peanuts (roasted) — ₱95 — unit: 250g pack
24. Muscovado Sugar — ₱110 — unit: 250g pack
25. Fresh Turmeric (Luyang Dilaw) — ₱60 — unit: 100g pack
**Implementation approach for the seed script:**
Write a PHP artisan command `php artisan demo:seed-products` in `app/Console/Commands/SeedDemoProducts.php`:
- The command should authenticate as the ULTIMATE user (via `Auth::loginUsingId($ultimateUserId)`)
- For each product: call `ProductController@createNew_Admin` logic directly (or use Eloquent to create `Product` + attach to `prd_str`)
- Use categories: Fresh Produce, Livestock & Poultry, Seafood, Grains & Cereals, Processed Goods
- Set `is_active=true`, realistic prices, realistic `available` stock (50500 units)
- After creating each product globally, attach to `DEMO_STORE_HASH` via the prd_str pivot: `Store::find($store->id)->products()->attach($product->id, ['price'=>$price, 'available'=>$stock, 'is_active'=>true])`
- Print summary table on completion
### Step 4 — Set up POS Access Key for the demo store
After the store exists, create a POS access key via the UI (`/pos-access-keys`) or directly:
```sql
INSERT INTO pos_access_keys (hashkey, access_key, terminal_name, store_id, is_active, created_by, updated_by, created_at, updated_at)
SELECT
CONCAT(UUID(), REPEAT(MD5(RAND()), 3)) as hashkey,
CONCAT('PK-DEMO-', UPPER(LEFT(MD5(RAND()), 8))) as access_key,
'Demo Counter 1' as terminal_name,
(SELECT id FROM str WHERE hashkey = '<DEMO_STORE_HASH>') as store_id,
1 as is_active,
(SELECT id FROM users WHERE acct_type='ULTIMATE' LIMIT 1) as created_by,
(SELECT id FROM users WHERE acct_type='ULTIMATE' LIMIT 1) as updated_by,
NOW() as created_at,
NOW() as updated_at;
```
Record the `access_key` value (starts with `PK-`) for use in POS demo.
### Step 5 — Simulate a POS session to generate demo history
```bash
curl -s -X POST http://localhost:9522/api/perf/pos/simulate \
-H "Content-Type: application/json" \
-H "X-Perf-Token: bukid-demo-seed-2026" \
-d '{
"store_hash": "<DEMO_STORE_HASH>",
"items": 5,
"cycles": 10,
"complete": true
}'
```
This creates 10 completed POS transactions with 5 items each, giving the POS History page real data.
### Step 6 — Verify via UltimateConsole SQL
Run these queries in UltimateConsole to confirm:
- `SELECT COUNT(*) FROM prd_items WHERE is_active=1` — expect ≥ 25
- `SELECT COUNT(*) FROM prd_str WHERE store_id=(SELECT id FROM str WHERE hashkey='<DEMO_STORE_HASH>')` — expect 25
- `SELECT COUNT(*) FROM pos_access_keys WHERE store_id=(SELECT id FROM str WHERE hashkey='<DEMO_STORE_HASH>')` — expect ≥ 1
- `SELECT COUNT(*) FROM pos_sessions WHERE store_id=(SELECT id FROM str WHERE hashkey='<DEMO_STORE_HASH>')` — expect ≥ 10
### Step 7 — Update presentation credentials note
Record for Playwright capture script (`/tmp/bukid-presentation/capture.js`):
- Store owner login: mobile `099`, password `polomiko32!`
- Demo store name: `BukidBounty Fresh Market` (first result)
- POS access key: `PK-DEMO-XXXXXXXX` (recorded in Step 4)
- Store hashkey: `<DEMO_STORE_HASH>`
## context
```
// Perf API endpoints (from PerformanceController.php / routes/api.php):
// GET /api/perf/ping — health check
// POST /api/perf/seed/stores — { count, owner_hash?, category?, prefix? }
// POST /api/perf/seed/products — { count, target_store_hash?, attach_to_store?, prefix? }
// POST /api/perf/pos/simulate — { store_hash, items?, cycles?, complete? }
// Auth: X-Perf-Token: <PERF_API_TOKEN env>
// Table names (canonical):
// str = stores
// prd_items = products
// prd_str = product-store pivot (price, available, is_active, description)
// pos_access_keys = POS terminal keys (prefix PK- for real terminals)
// pos_sessions = POS sessions
// Product model: App\Models\Market\Product
// Store model: App\Models\Market\Store
// Product↔Store attach: $store->products()->attach($product->id, ['price'=>..., 'available'=>..., 'is_active'=>true])
// ModelSavingListener auto-sets hashkey, created_by, updated_by for Eloquent saves
// Artisan command skeleton:
// php artisan make:command SeedDemoProducts
// class SeedDemoProducts extends Command { protected $signature = 'demo:seed-products {store_hash}'; }
```
## notes
- dictionary: `ai-docs/dictionary.md`
- linters: none — this is a data seeding task, no Vue/PHP linting needed
- constraints:
- Server must be running before executing curl commands (user confirmed server is currently down — this task runs later)
- The artisan command approach is preferred over direct SQL inserts for products because ModelSavingListener auto-populates hashkey/created_by/updated_by
- For pos_access_keys and SQL steps, manually include all required fields (created_by, updated_by, created_at, updated_at, hashkey) since raw SQL bypasses Eloquent events
- Perf seeder prefix names are synthetic ("BukidBounty Fresh Market-001") — use the prefix param to set the store name close to desired then rename via UI if needed
- Do not truncate existing data before seeding; additive only