|
| 1 | +import type { MicroRoleDefinition, MicroRoleId } from "@/data/microRoles"; |
| 2 | +import type { MicroRoleScore } from "@/engine/patternSignature"; |
| 3 | + |
| 4 | +export interface MicroRoleNarrative { |
| 5 | + observable: string[]; |
| 6 | + dailyHabits: string[]; |
| 7 | + underPressure: string[]; |
| 8 | + communicationOn: string[]; |
| 9 | + communicationResistance: string[]; |
| 10 | + analogy: string; |
| 11 | + blindSpot: string; |
| 12 | +} |
| 13 | + |
| 14 | +const NARRATIVES: Partial<Record<MicroRoleId, MicroRoleNarrative>> = { |
| 15 | + information_collector: { |
| 16 | + observable: [ |
| 17 | + "Sering merasa perlu mengumpulkan bahan, referensi, atau konteks sebelum merasa cukup yakin.", |
| 18 | + "Lebih mudah percaya pada penjelasan yang punya dasar, bukan hanya kesan umum.", |
| 19 | + ], |
| 20 | + dailyHabits: [ |
| 21 | + "Menyimpan catatan, link, foto, barang, atau informasi karena merasa suatu saat bisa berguna.", |
| 22 | + "Sering bertanya detail tambahan sebelum mengambil kesimpulan.", |
| 23 | + ], |
| 24 | + underPressure: [ |
| 25 | + "Saat terdesak, cenderung mencari data tambahan atau mengumpulkan konteks agar keputusan tidak terasa kosong.", |
| 26 | + ], |
| 27 | + communicationOn: ["Ajak dengan pertanyaan berbasis data, contoh nyata, dan ruang untuk mengecek konteks."], |
| 28 | + communicationResistance: ["Jangan memaksa keputusan cepat sambil menutup akses pada informasi yang dianggap penting."], |
| 29 | + analogy: "Seperti perpustakaan berjalan: banyak bahan disimpan bukan untuk dipamerkan, tetapi agar bisa dipakai saat dibutuhkan.", |
| 30 | + blindSpot: "Bisa terlalu lama menunggu informasi terasa lengkap sebelum bergerak.", |
| 31 | + }, |
| 32 | + fast_learner: { |
| 33 | + observable: [ |
| 34 | + "Mudah tertarik pada hal baru yang membuat kapasitas diri naik.", |
| 35 | + "Cepat hidup ketika ada tantangan belajar atau kesempatan memahami sesuatu lebih dalam.", |
| 36 | + ], |
| 37 | + dailyHabits: ["Mencari tutorial, penjelasan, kursus, atau referensi ketika menemukan bidang baru.", "Mudah bosan jika hanya diminta mengulang pola yang tidak memberi pembelajaran."], |
| 38 | + underPressure: ["Saat tertekan, cenderung mencoba memahami cepat apa yang belum diketahui agar bisa mengejar situasi."], |
| 39 | + communicationOn: ["Beri ruang belajar, alasan, dan kesempatan berkembang; bukan hanya instruksi kaku."], |
| 40 | + communicationResistance: ["Jangan meremehkan rasa ingin tahunya atau memaksa rutinitas tanpa makna belajar."], |
| 41 | + analogy: "Seperti mesin yang menyala ketika diberi bahan bakar pengetahuan baru.", |
| 42 | + blindSpot: "Bisa terlalu sering pindah minat jika tidak ada prioritas yang jelas.", |
| 43 | + }, |
| 44 | + deep_thinker: { |
| 45 | + observable: ["Tidak selalu langsung bereaksi, tetapi sering membawa pemikiran yang lebih matang setelah diberi waktu.", "Mencari makna, filosofi, atau alasan lebih dalam di balik sebuah peristiwa."], |
| 46 | + dailyHabits: ["Merenung sendiri, menulis catatan, atau memutar ulang percakapan untuk memahami maknanya.", "Butuh jeda sebelum memberi jawaban penting."], |
| 47 | + underPressure: ["Saat tertekan, cenderung masuk ke dalam pikiran untuk menyusun makna sebelum merespons."], |
| 48 | + communicationOn: ["Beri waktu memproses; ajukan pertanyaan yang membuka refleksi, bukan hanya tuntutan respons cepat."], |
| 49 | + communicationResistance: ["Jangan menganggap diam sebagai tidak peduli; bisa jadi ia sedang menyusun pemahaman."], |
| 50 | + analogy: "Seperti sumur dalam: tidak selalu ramai di permukaan, tetapi menyimpan kedalaman yang bisa diambil ketika waktunya tepat.", |
| 51 | + blindSpot: "Bisa tampak jauh atau lambat merespons saat orang lain butuh keputusan segera.", |
| 52 | + }, |
| 53 | + idea_translator: { |
| 54 | + observable: ["Mampu membuat hal rumit terdengar lebih sederhana dan bisa dipahami orang lain.", "Sering menjadi jembatan antara ide, bahasa, dan pemahaman orang."], |
| 55 | + dailyHabits: ["Menjelaskan ulang sesuatu dengan bahasa sendiri.", "Membuat analogi, contoh, atau alur penjelasan agar orang lain lebih cepat menangkap maksud."], |
| 56 | + underPressure: ["Saat tertekan, cenderung mencoba menjelaskan posisi, alasan, atau pola pikir agar situasi menjadi lebih jernih."], |
| 57 | + communicationOn: ["Tanya pendapatnya tentang cara menjelaskan, menyusun pesan, atau membuat orang lain mengerti."], |
| 58 | + communicationResistance: ["Jangan memotong penjelasannya terlalu cepat sebelum pola pikirnya selesai tersusun."], |
| 59 | + analogy: "Seperti penerjemah ruangan: mengambil ide yang masih berantakan lalu memberi bahasa yang bisa dimengerti bersama.", |
| 60 | + blindSpot: "Bisa terlalu banyak menjelaskan ketika orang lain sebenarnya hanya butuh keputusan singkat.", |
| 61 | + }, |
| 62 | + strategy_designer: { |
| 63 | + observable: ["Cepat membaca beberapa kemungkinan jalan dan mencari rute yang paling masuk akal.", "Lebih tertarik pada arah, prioritas, dan kemungkinan daripada sekadar menjalankan rutinitas."], |
| 64 | + dailyHabits: ["Sering bertanya: opsi terbaiknya apa, risikonya apa, jalan lainnya apa?", "Mudah tertarik pada skenario, peta jalan, dan solusi alternatif."], |
| 65 | + underPressure: ["Saat terdesak, cenderung makin aktif mencari celah, strategi, dan jalan keluar."], |
| 66 | + communicationOn: ["Ajak bicara soal strategi, kemungkinan, trade-off, dan arah keputusan."], |
| 67 | + communicationResistance: ["Jangan langsung mengunci pilihan tanpa memberi ruang melihat opsi lain."], |
| 68 | + analogy: "Seperti navigator: bukan hanya melihat jalan di depan, tetapi mencari rute paling masuk akal menuju tujuan.", |
| 69 | + blindSpot: "Bisa tidak sabar pada proses yang terasa tanpa arah atau terlalu administratif.", |
| 70 | + }, |
| 71 | + idea_synthesizer: { |
| 72 | + observable: ["Sering menghubungkan banyak ide menjadi bentuk baru yang lebih utuh.", "Mudah melihat hubungan antarhal yang bagi orang lain tampak terpisah."], |
| 73 | + dailyHabits: ["Menggabungkan referensi, pengalaman, dan ide menjadi konsep baru.", "Membuat rangkuman atau kerangka baru dari banyak informasi."], |
| 74 | + underPressure: ["Saat tertekan, cenderung merangkai ulang informasi untuk menemukan gambaran baru yang lebih masuk akal."], |
| 75 | + communicationOn: ["Beri ruang brainstorming, peta konsep, dan diskusi kemungkinan."], |
| 76 | + communicationResistance: ["Jangan terlalu cepat membunuh ide sebelum bentuknya sempat matang."], |
| 77 | + analogy: "Seperti dapur ide: bahan-bahan berbeda diolah menjadi menu baru yang lebih bermakna.", |
| 78 | + blindSpot: "Bisa membuka terlalu banyak kemungkinan sehingga keputusan tertunda.", |
| 79 | + }, |
| 80 | + pattern_reader: { |
| 81 | + observable: ["Tidak mudah puas dengan jawaban permukaan; ingin melihat data, pola, dan hubungan sebab-akibat.", "Sering menemukan struktur di balik situasi yang tampak acak."], |
| 82 | + dailyHabits: ["Membandingkan angka, fakta, pola kejadian, atau bukti sebelum menerima kesimpulan.", "Menyukai penjelasan yang logis dan dapat ditelusuri."], |
| 83 | + underPressure: ["Saat terdesak, cenderung mengurai fakta dan mencari pola yang bisa dipercaya."], |
| 84 | + communicationOn: ["Beri data, alasan, dan struktur berpikir yang jelas."], |
| 85 | + communicationResistance: ["Jangan memakai alasan 'pokoknya' atau 'sudah biasa begitu' untuk keputusan penting."], |
| 86 | + analogy: "Seperti analis sinyal: mencari pola yang tersembunyi di balik noise.", |
| 87 | + blindSpot: "Bisa terlihat kritis atau sulit diyakinkan ketika bukti belum cukup.", |
| 88 | + }, |
| 89 | + problem_restorer: { |
| 90 | + observable: ["Tertarik mencari penyebab masalah dan membuat sesuatu kembali berjalan.", "Lebih hidup ketika ada kerusakan, kekacauan, atau error yang bisa diperbaiki."], |
| 91 | + dailyHabits: ["Mencari akar masalah, mencoba solusi, lalu mengecek apakah sistem kembali normal.", "Sulit membiarkan masalah menggantung tanpa usaha perbaikan."], |
| 92 | + underPressure: ["Saat tertekan, cenderung masuk ke mode troubleshooting: apa penyebabnya, apa yang harus diperbaiki dulu?"], |
| 93 | + communicationOn: ["Ajak dengan problem statement yang jelas dan beri ruang menganalisis akar masalah."], |
| 94 | + communicationResistance: ["Jangan hanya menyuruh menerima kondisi rusak tanpa kesempatan memperbaiki."], |
| 95 | + analogy: "Seperti teknisi pemulih: tenang ketika bisa menemukan titik gangguan dan mengembalikan fungsi.", |
| 96 | + blindSpot: "Bisa terlalu fokus memperbaiki sesuatu yang sebenarnya tidak perlu diselamatkan.", |
| 97 | + }, |
| 98 | + people_developer: { |
| 99 | + observable: ["Mudah melihat potensi orang lain dan senang ketika ada orang yang bertumbuh.", "Sering memberi dorongan, feedback, atau dukungan agar orang lebih mampu."], |
| 100 | + dailyHabits: ["Menyadari kemajuan kecil orang lain.", "Memberi semangat atau arahan agar orang tidak menyerah terlalu cepat."], |
| 101 | + underPressure: ["Saat tertekan, cenderung tetap memikirkan bagaimana orang lain bisa dibantu atau dinaikkan kapasitasnya."], |
| 102 | + communicationOn: ["Bicarakan perkembangan, proses belajar, dan dampak positif pada orang lain."], |
| 103 | + communicationResistance: ["Jangan membuatnya merasa usahanya membantu orang tidak dihargai."], |
| 104 | + analogy: "Seperti tukang kebun manusia: memperhatikan tunas kecil dan ingin melihatnya tumbuh.", |
| 105 | + blindSpot: "Bisa terlalu memikul proses tumbuh orang lain sampai lupa batas diri.", |
| 106 | + }, |
| 107 | + system_organizer: { |
| 108 | + observable: ["Merasa lebih lega ketika ruang, barang, jadwal, atau proses menjadi rapi dan bisa diprediksi.", "Mudah melihat bagian yang berantakan dan ingin menatanya."], |
| 109 | + dailyHabits: ["Membuat daftar, merapikan file, mengatur ruang, atau membuat sistem agar mudah dicari.", "Merasa terganggu jika sesuatu sering berubah tanpa alasan jelas."], |
| 110 | + underPressure: ["Saat tertekan, cenderung mencari struktur: apa urutannya, siapa melakukan apa, kapan selesai?"], |
| 111 | + communicationOn: ["Berikan kejelasan langkah, jadwal, dan tanggung jawab."], |
| 112 | + communicationResistance: ["Jangan membuat perubahan mendadak tanpa konteks atau aturan baru yang jelas."], |
| 113 | + analogy: "Seperti penata ruang kontrol: semua indikator harus jelas agar sistem bisa dijalankan dengan tenang.", |
| 114 | + blindSpot: "Bisa tampak kaku saat situasi memang membutuhkan improvisasi.", |
| 115 | + }, |
| 116 | + commitment_keeper: { |
| 117 | + observable: ["Serius memegang janji, tanggung jawab, dan kualitas hasil.", "Tidak nyaman jika pekerjaan dibuat asal selesai."], |
| 118 | + dailyHabits: ["Mengingat kewajiban, memperbaiki kesalahan, dan merasa perlu menuntaskan yang sudah dijanjikan.", "Sulit santai jika ada tanggung jawab yang belum beres."], |
| 119 | + underPressure: ["Saat tertekan, cenderung memikul lebih banyak karena merasa harus bertanggung jawab."], |
| 120 | + communicationOn: ["Bicarakan komitmen, kepercayaan, standar mutu, dan pembagian tanggung jawab yang adil."], |
| 121 | + communicationResistance: ["Jangan menggampangkan janji atau membuatnya merasa sendirian memikul beban."], |
| 122 | + analogy: "Seperti jangkar: menjaga agar komitmen tidak mudah hanyut oleh keadaan.", |
| 123 | + blindSpot: "Bisa merasa bersalah berlebihan atau sulit mendelegasikan." , |
| 124 | + }, |
| 125 | + social_connector: { |
| 126 | + observable: ["Mudah membuka percakapan dan membuat suasana lebih hidup.", "Kehadirannya dapat membuat kelompok terasa lebih ramai, cair, atau terbuka."], |
| 127 | + dailyHabits: ["Menyapa orang, membuka obrolan, atau menghubungkan satu orang dengan orang lain.", "Merasa penasaran dengan orang baru atau suasana sosial baru."], |
| 128 | + underPressure: ["Saat tertekan, bisa mencoba mencairkan suasana agar ketegangan tidak terlalu berat."], |
| 129 | + communicationOn: ["Mulai dengan sapaan hangat, cerita ringan, dan ruang interaksi yang manusiawi."], |
| 130 | + communicationResistance: ["Jangan membuat relasi terasa dingin, formal berlebihan, atau hanya transaksional."], |
| 131 | + analogy: "Seperti pemantik suasana: ruangan yang datar bisa terasa lebih hidup saat ia hadir.", |
| 132 | + blindSpot: "Bisa menghabiskan energi sosial jika terlalu banyak membuka koneksi tanpa batas." , |
| 133 | + }, |
| 134 | + harmony_keeper: { |
| 135 | + observable: ["Mencari titik temu dan menurunkan ketegangan agar hubungan tidak rusak.", "Lebih nyaman ketika perbedaan bisa dibicarakan dengan tenang."], |
| 136 | + dailyHabits: ["Menghindari kata-kata yang terlalu menusuk.", "Mencari kalimat tengah agar kedua pihak tidak merasa diserang."], |
| 137 | + underPressure: ["Saat tertekan, cenderung berusaha menenangkan konflik atau menunda ledakan emosi."], |
| 138 | + communicationOn: ["Gunakan nada tenang, akui sudut pandangnya, lalu ajak mencari jalan tengah."], |
| 139 | + communicationResistance: ["Jangan menyerang secara frontal atau mempermalukan di depan orang lain."], |
| 140 | + analogy: "Seperti peredam getaran: membantu sistem tetap stabil saat gesekan mulai naik.", |
| 141 | + blindSpot: "Bisa terlalu lama menghindari keputusan tegas demi menjaga suasana." , |
| 142 | + }, |
| 143 | + decision_director: { |
| 144 | + observable: ["Berani mengambil posisi, menghadapi percakapan sulit, dan memberi arah.", "Tidak nyaman jika keputusan penting terus digantung."], |
| 145 | + dailyHabits: ["Langsung bertanya inti masalah atau arah keputusan.", "Lebih suka kejelasan daripada terlalu banyak basa-basi."], |
| 146 | + underPressure: ["Saat terdesak, cenderung mengambil kontrol dan menentukan arah agar situasi tidak melebar."], |
| 147 | + communicationOn: ["Bicarakan tujuan, batas, keputusan, dan konsekuensi secara jelas."], |
| 148 | + communicationResistance: ["Jangan membuatnya merasa diputar-putar tanpa kejelasan posisi."], |
| 149 | + analogy: "Seperti kemudi darurat: ketika situasi kabur, ia ingin segera menentukan arah." , |
| 150 | + blindSpot: "Bisa terasa terlalu keras jika ketegasan tidak diimbangi ruang mendengar." , |
| 151 | + }, |
| 152 | + quality_evaluator: { |
| 153 | + observable: ["Teliti melihat ketidaksesuaian, kekurangan, atau risiko mutu.", "Tidak mudah puas sebelum sesuatu terasa benar, aman, dan layak."], |
| 154 | + dailyHabits: ["Memeriksa ulang dokumen, angka, detail, atau prosedur.", "Mudah melihat bagian kecil yang dilewatkan orang lain."], |
| 155 | + underPressure: ["Saat tertekan, cenderung memperketat pemeriksaan agar kesalahan tidak lolos."], |
| 156 | + communicationOn: ["Beri kriteria kualitas, bukti, dan ruang untuk menguji hasil."], |
| 157 | + communicationResistance: ["Jangan menganggap pertanyaan detail sebagai serangan; sering kali itu cara menjaga mutu."], |
| 158 | + analogy: "Seperti quality gate: memastikan sesuatu layak lewat sebelum dipakai lebih luas.", |
| 159 | + blindSpot: "Bisa terlalu fokus pada yang belum benar sehingga apresiasi kurang terdengar." , |
| 160 | + }, |
| 161 | + creative_designer: { |
| 162 | + observable: ["Mudah membayangkan bentuk, cerita, visual, atau konsep baru.", "Sering membuat sesuatu terasa lebih menarik atau punya rasa."], |
| 163 | + dailyHabits: ["Menyukai referensi visual, desain, musik, cerita, atau bentuk presentasi yang punya karakter.", "Mencoba versi baru dari sesuatu yang biasa."], |
| 164 | + underPressure: ["Saat tertekan, bisa mencari cara kreatif agar situasi tidak buntu."], |
| 165 | + communicationOn: ["Beri ruang eksplorasi, referensi, dan izin membuat versi yang lebih menarik."], |
| 166 | + communicationResistance: ["Jangan terlalu cepat membatasi bentuk sebelum proses eksplorasinya terlihat."], |
| 167 | + analogy: "Seperti studio kecil di kepala: hal sederhana bisa diolah menjadi bentuk yang punya rasa." , |
| 168 | + blindSpot: "Bisa kehilangan energi jika terlalu lama dipaksa mengikuti format kaku." , |
| 169 | + }, |
| 170 | +}; |
| 171 | + |
| 172 | +export function getMicroRoleNarrative(role: MicroRoleDefinition): MicroRoleNarrative { |
| 173 | + return ( |
| 174 | + NARRATIVES[role.id] ?? { |
| 175 | + observable: [role.visible], |
| 176 | + dailyHabits: [role.tagline], |
| 177 | + underPressure: [`Saat tertekan, kecenderungan ${role.name.toLowerCase()} dapat muncul sebagai cara menjaga kontrol dan memahami situasi.`], |
| 178 | + communicationOn: [`Masuk lewat bahasa yang sesuai dengan ${role.name.toLowerCase()}: beri konteks, ruang, dan alasan yang jelas.`], |
| 179 | + communicationResistance: [role.risk], |
| 180 | + analogy: role.tagline, |
| 181 | + blindSpot: role.risk, |
| 182 | + } |
| 183 | + ); |
| 184 | +} |
| 185 | + |
| 186 | +function unique(items: string[], limit: number): string[] { |
| 187 | + const seen = new Set<string>(); |
| 188 | + const output: string[] = []; |
| 189 | + for (const item of items) { |
| 190 | + if (!item || seen.has(item)) continue; |
| 191 | + seen.add(item); |
| 192 | + output.push(item); |
| 193 | + if (output.length >= limit) break; |
| 194 | + } |
| 195 | + return output; |
| 196 | +} |
| 197 | + |
| 198 | +export function buildObservablePatterns(roles: MicroRoleScore[], limit = 5): string[] { |
| 199 | + return unique(roles.flatMap((role) => getMicroRoleNarrative(role).observable), limit); |
| 200 | +} |
| 201 | + |
| 202 | +export function buildDailyHabits(roles: MicroRoleScore[], limit = 5): string[] { |
| 203 | + return unique(roles.flatMap((role) => getMicroRoleNarrative(role).dailyHabits), limit); |
| 204 | +} |
| 205 | + |
| 206 | +export function buildPressurePatterns(roles: MicroRoleScore[], limit = 4): string[] { |
| 207 | + return unique(roles.flatMap((role) => getMicroRoleNarrative(role).underPressure), limit); |
| 208 | +} |
| 209 | + |
| 210 | +export function buildCommunicationOn(roles: MicroRoleScore[], limit = 4): string[] { |
| 211 | + return unique(roles.flatMap((role) => getMicroRoleNarrative(role).communicationOn), limit); |
| 212 | +} |
| 213 | + |
| 214 | +export function buildCommunicationResistance(roles: MicroRoleScore[], limit = 4): string[] { |
| 215 | + return unique(roles.flatMap((role) => getMicroRoleNarrative(role).communicationResistance), limit); |
| 216 | +} |
| 217 | + |
| 218 | +export function buildAnalogies(roles: MicroRoleScore[], limit = 3): string[] { |
| 219 | + return unique(roles.map((role) => getMicroRoleNarrative(role).analogy), limit); |
| 220 | +} |
| 221 | + |
| 222 | +export function buildBlindSpots(roles: MicroRoleScore[], limit = 4): string[] { |
| 223 | + return unique(roles.map((role) => getMicroRoleNarrative(role).blindSpot), limit); |
| 224 | +} |
0 commit comments