
## Sistem aktivitas employee

Scene PlayCanvas, kamera, meja, dan geometri employee tetap memakai implementasi existing.
Posisi meja yang semula dihitung dalam renderer dipindahkan ke `activity-config.js`
dengan rumus yang sama. Avatar tetap merupakan anak objek meja; renderer menerjemahkan
posisi dunia brain ke posisi lokal avatar. Brain tetap hidup saat berpindah ruang.

File baru:
- `public/assets/js/virtual-office/activity-config.js`: posisi meja, waypoint fasilitas,
  jalur koridor, kecepatan, durasi, probabilitas, prioritas, dan interval.
- `public/assets/js/virtual-office/employee-brain.js`: EmployeeBrain dan EmployeeActivityManager.
- `tests/JavaScript/employee-brain.test.cjs`: tes state machine tanpa membutuhkan WebGL.

`workState` (`idle`, `working`, `waiting`, `error`, `success`) berbeda dari
`activityState` (`sitting`, `typing`, `standing`, `walking`, `drinking`, `toilet`,
`pantry`, `talking`, `meeting`, `returning_to_desk`). `active` dari daftar workflow
hanya mengatur warna monitor, bukan menentukan apakah employee sedang bekerja.

Manager menjalankan keputusan perilaku setiap 250 ms. Movement dihitung pada update
loop existing menggunakan kecepatan 1.6 unit/detik. Keputusan random hanya terjadi
pada deadline 20–60 detik, dengan bobot 45/20/15/10/5/5 untuk diam/jalan/minum/bicara/
toilet/pantry. Conversation mereservasi kedua employee dan memakai cooldown 60 detik.
Brain memiliki satu token aktivitas: pembatalan membuang path, timer, callback lama,
visibility toilet dan reservasi partner sebelum kembali ke meja. Pekerjaan n8n
membatalkan aktivitas ambient; `working` baru typing setelah tiba kembali di meja.
Error menghentikan typing. Success tampil empat detik lalu idle, tanpa berulang untuk
ID eksekusi sukses yang sama. Semua durasi mengikuti waktu simulasi; Jeda animasi
atau tab tersembunyi menghentikan gerakan/scheduler, tetapi status yang sudah diterima
tetap bisa memperbarui work state.

Endpoint GET `/virtual-office/{employee}/work-state` memakai auth + superadmin dan
memeriksa tag employee. Browser melakukan polling ulang 15 detik setelah satu siklus
selesai, maksimal tiga permintaan paralel. Backend membaca running, waiting, lalu
riwayat terakhir, tanpa data node. Respons gagal atau status tak dikenal ditandai
UNAVAILABLE: state terakhir dipertahankan, aktivitas ambient baru tidak diizinkan.
Pada versi n8n yang menolak filter running, modal menampilkan catatan keterbatasan;
pekerjaan yang tidak diekspos oleh API tidak bisa dideteksi secara real-time. Eksekusi
singkat di antara polling bisa terlewat. Tidak ada pemanggilan endpoint internal n8n.

Waypoint water dispenser, pantry, toilet dan meeting room merupakan interaction
point konfigurasi, bukan objek fasilitas baru. Toilet menyembunyikan avatar 5–10 detik;
minum memakai pose tangan dan timer 3–5 detik. Route adapter memakai koridor di sekitar
meja dan sisi kanan ruangan; belum ada navmesh atau penghindaran tabrakan antar-avatar.
Log aktivitas hanya disimpan dalam memori browser, maksimum 100 entri dan 20 entri
employee terpilih ditampilkan dalam modal. Tidak ada tabel database baru.

## Pengujian manual aktivitas

1. Pada environment `local` atau `development`, buka Virtual Office sebagai superadmin.
   Kontrol debug tidak dirender pada production. Jangan mengubah production menjadi local.
2. Klik employee → modal menampilkan Work Status, Current Activity, Target, Last Activity,
   dan Log aktivitas visual. Nama di atas avatar juga dapat dipilih melalui keyboard.
3. **Working**: klik `Work`. Employee yang sedang bergerak pulang ke meja kemudian typing.
   Untuk sumber nyata, jalankan workflow dari n8n dan biarkan cukup lama agar teramati polling.
4. **Get Water**: klik `Idle`, tunggu employee di meja, lalu `Get Water`. Tutup modal
   untuk melihat employee berdiri, berjalan, minum, dan pulang. Klik lagi avatar/nama untuk log.
5. **Toilet**: setelah idle di meja, klik `Toilet`; avatar berjalan, tersembunyi 5–10 detik,
   muncul di interaction point yang sama, lalu kembali tanpa teleport.
6. **Talk**: siapkan dua employee idle di ruang yang sama; setelah cooldown 60 detik habis,
   pilih salah satu lalu `Talk`. Keduanya saling menghadap; setelah 3–8 detik pengunjung pulang.
7. **Interruption**: saat employee sedang `Get Water`, klik `Work`. Timer aktivitas lama
   tidak boleh mengembalikan employee ke idle. Coba juga Work saat toilet atau talking.
8. Klik `Success`: indikator muncul empat detik lalu idle. Klik `Error`: label merah ERROR,
   employee di meja dan tidak typing. `Return Desk` membatalkan ambient, bukan work state.
9. Pindah ruang lalu kembali: brain tidak direset. Uji minimal 20 workflow bertag employee.

Debug mengubah simulasi di browser saja, bukan menjalankan/menonaktifkan workflow.
Polling berikutnya dapat menggantikan simulasi dengan status n8n yang sebenarnya.
Jika tombol ditolak, periksa work state, posisi meja, partner, dan cooldown di modal.

Tes otomatis:

```sh
node --test tests/JavaScript/employee-brain.test.cjs
vendor/bin/phpunit tests/Feature/VirtualOfficeTest.php
```

TODO lanjutan:
- Uji visual dan FPS pada browser/perangkat target dengan minimal 20 employee.
- Navmesh/pathfinding dan antrean/reservasi fasilitas untuk menghindari avatar berimpitan.
- Model fasilitas dan animation clips khusus, jika asetnya tersedia.
- Event/webhook n8n terautentikasi untuk pekerjaan singkat atau versi API yang tidak
  mengekspos eksekusi running; polling saat ini bukan stream real-time.
- Koordinasi meeting lintas employee dan persistensi log bila nantinya diperlukan.
