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

8.9 KiB
Raw Blame History

task, cycles, context, private, started, finished
task cycles context private started finished
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 3 true false 2026-05-16T00:00:00Z 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

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

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:

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

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