hanoman 0.1.59 → 0.2.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hanoman",
3
- "version": "0.1.59",
3
+ "version": "0.2.0",
4
4
  "description": "Orchestrator + dashboard workflow docs-driven untuk sesi Claude Code / Codex",
5
5
  "type": "module",
6
6
  "repository": {
@@ -0,0 +1,45 @@
1
+ -- SPEC-945 · ADR-0150 · fondasi papan tim: direktori orang + kartu kerja manusia.
2
+ --
3
+ -- Ditulis tangan (bukan `migrate dev`): worktree tetangga membuat `migrate dev` me-reset DB saat
4
+ -- ada drift. ADITIF murni — dua tabel BARU, tak ada tabel diredefinisi, tanpa backfill.
5
+ --
6
+ -- `Member.id` deterministik (email ternormalisasi) ditulis aplikasi, bukan default DB: itulah yang
7
+ -- mencegah dua mesin melahirkan dua baris untuk orang yang sama (pola CustomAgent, ADR-0094).
8
+ -- `Task.specId` sengaja TANPA FOREIGN KEY, cermin Ticket.specId: changefeed bisa memancarkan Task
9
+ -- sebelum Spec-nya mendarat (kelas SPEC-382), dan FK akan menolaknya.
10
+ CREATE TABLE "Member" (
11
+ "id" TEXT NOT NULL PRIMARY KEY,
12
+ "name" TEXT NOT NULL,
13
+ "email" TEXT NOT NULL,
14
+ "role" TEXT,
15
+ "active" BOOLEAN NOT NULL DEFAULT true,
16
+ "version" INTEGER NOT NULL DEFAULT 0,
17
+ "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
18
+ "updatedAt" DATETIME NOT NULL
19
+ );
20
+
21
+ CREATE UNIQUE INDEX "Member_email_key" ON "Member" ("email");
22
+
23
+ CREATE TABLE "Task" (
24
+ "id" TEXT NOT NULL PRIMARY KEY,
25
+ "projectId" TEXT,
26
+ "title" TEXT NOT NULL,
27
+ "detail" TEXT,
28
+ "status" TEXT NOT NULL,
29
+ "priority" TEXT NOT NULL DEFAULT 'sedang',
30
+ "memberId" TEXT,
31
+ "startDate" DATETIME,
32
+ "dueDate" DATETIME,
33
+ "order" REAL NOT NULL DEFAULT 0,
34
+ "specId" TEXT,
35
+ "version" INTEGER NOT NULL DEFAULT 0,
36
+ "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
37
+ "updatedAt" DATETIME NOT NULL,
38
+ CONSTRAINT "Task_projectId_fkey" FOREIGN KEY ("projectId")
39
+ REFERENCES "Project" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
40
+ CONSTRAINT "Task_memberId_fkey" FOREIGN KEY ("memberId")
41
+ REFERENCES "Member" ("id") ON DELETE SET NULL ON UPDATE CASCADE
42
+ );
43
+
44
+ CREATE INDEX "Task_projectId_status_idx" ON "Task" ("projectId", "status");
45
+ CREATE INDEX "Task_memberId_idx" ON "Task" ("memberId");
@@ -35,6 +35,7 @@ model Project {
35
35
  changelogs Changelog[] // SPEC-516 · ADR-0105 · changelog tersimpan project ini
36
36
  clientAccess ClientProjectAccess[] // SPEC-617 · ADR-0110 · akun klien yang boleh melihat project ini
37
37
  portalChats PortalChatSession[] // SPEC-854 · ADR-0129 · percakapan portal klien project ini
38
+ tasks Task[] // SPEC-945 · ADR-0150 · kartu kerja manusia di project ini
38
39
  }
39
40
 
40
41
  model Spec {
@@ -176,6 +177,68 @@ model CustomAgent {
176
177
  @@index([projectId])
177
178
  }
178
179
 
180
+ // SPEC-945 · ADR-0150 · direktori orang untuk papan tim. GLOBAL, bukan per project: Task boleh
181
+ // tanpa project, jadi direktori orang tak bisa digantung pada project — dan orang yang sama lazim
182
+ // melintasi beberapa project.
183
+ //
184
+ // `id` DETERMINISTIK dari email ternormalisasi (lowercase + trim) ditulis aplikasi, bukan default
185
+ // DB — alasan yang sama dengan CustomAgent (ADR-0094): dengan id acak, dua mesin yang sama-sama
186
+ // membuat "Dena" melahirkan dua baris yang keduanya menyeberang changefeed, dan salah satunya
187
+ // lenyap tanpa jejak begitu papan menyaring per-assignee.
188
+ //
189
+ // Konsekuensinya `email` IMMUTABLE, ditegakkan di boundary route: ganti email = hapus + buat baru.
190
+ // `@unique` di sini bukan redundansi terhadap PK — id menyimpan bentuk ternormalisasi, kolom ini
191
+ // menyimpan yang diketik operator.
192
+ model Member {
193
+ id String @id
194
+ name String
195
+ email String @unique
196
+ role String? // label bebas: "desainer", "backend" — BUKAN RBAC
197
+ active Boolean @default(true)
198
+ version Int @default(0) // SPEC-213 · version-stamp sync (ADR-0045)
199
+ createdAt DateTime @default(now())
200
+ updatedAt DateTime @updatedAt
201
+ tasks Task[]
202
+ }
203
+
204
+ // SPEC-945 · ADR-0150 · satuan kerja MANUSIA. Bukan Spec: kolomnya milik manusia dan bebas
205
+ // di-drag, sementara `Spec.stage` diturunkan dari fase sesi (ADR-0008/0024).
206
+ //
207
+ // `specId` sengaja TANPA FK (cermin Ticket.specId, ADR-0062): changefeed bisa memancarkan Task
208
+ // sebelum Spec-nya mendarat (kelas SPEC-382) dan FK akan menolaknya.
209
+ //
210
+ // TIDAK ada kolom `stage`: cermin stage backlog dihitung saat baca lewat join specId → Spec.stage.
211
+ // Aturan ADR-0090 bukan "selalu simpan" melainkan bisakah dihitung ulang dari sumber lain; di sini
212
+ // bisa, jadi kolom kedua hanya menciptakan dua kebenaran yang bisa drift.
213
+ //
214
+ // TIDAK ada `doneAt` dan tak ada stempel transisi kolom: Gantt yang dipilih rencana-saja, jadi
215
+ // tanggal aktual belum punya pembaca. Dihilangkan dengan sengaja, bukan terlupa.
216
+ //
217
+ // `order` Float, bukan Int: drop di antara dua kartu menulis titik tengah tetangganya — tak ada
218
+ // reindex seluruh kolom, dan dua mesin yang menulis bersamaan menghasilkan nilai yang tetap
219
+ // terurut. Seri dipecah oleh `id`.
220
+ model Task {
221
+ id String @id @default(cuid())
222
+ projectId String? // null = tugas internal tim, tanpa project
223
+ title String
224
+ detail String?
225
+ status String // backlog | doing | review | done (zTaskStatus)
226
+ priority String @default("sedang") // zPriority — kosakata yang sama dengan Spec
227
+ memberId String? // null = belum ditugaskan
228
+ startDate DateTime?
229
+ dueDate DateTime?
230
+ order Float @default(0)
231
+ specId String? // soft-link Spec hasil eskalasi
232
+ version Int @default(0) // SPEC-213 · version-stamp sync (ADR-0045)
233
+ createdAt DateTime @default(now())
234
+ updatedAt DateTime @updatedAt
235
+ project Project? @relation(fields: [projectId], references: [id], onDelete: Cascade)
236
+ member Member? @relation(fields: [memberId], references: [id], onDelete: SetNull)
237
+
238
+ @@index([projectId, status])
239
+ @@index([memberId])
240
+ }
241
+
179
242
  // SPEC-471 · ADR-0095 · cermin issue GitHub sebagai record lokal, pola Ticket (ADR-0062).
180
243
  // `id` DETERMINISTIK "<projectId>:<owner>/<repo>#<number>" ditulis aplikasi, bukan default DB —
181
244
  // alasan yang sama dengan CustomAgent (ADR-0094): dua mesin yang menarik repo yang sama harus