AP2.2a: Archetyp-Starter-Kits und MVP Execution Plan v0.2.
All checks were successful
Deploy Development / deploy (push) Successful in 45s
Test Suite / pytest-backend (push) Successful in 2m40s
Test Suite / lint-backend (push) Successful in 3s
Test Suite / compose-smoke (push) Has been skipped
Test Suite / k6 /api/health Baseline (push) Successful in 18s
Test Suite / playwright-smoke (push) Successful in 13s
All checks were successful
Deploy Development / deploy (push) Successful in 45s
Test Suite / pytest-backend (push) Successful in 2m40s
Test Suite / lint-backend (push) Successful in 3s
Test Suite / compose-smoke (push) Has been skipped
Test Suite / k6 /api/health Baseline (push) Successful in 18s
Test Suite / playwright-smoke (push) Successful in 13s
Referenz-Vorhaben A1/A2/B2b/B2a per UI anlegbar mit gefuehrter Starter-Struktur; Dogfooding-Seed deprecated. Plan-Korrektur: Execution Plan v0.2 statt Seed-Spiegel als Prioritaet. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
a097a82e17
commit
2b0d5dd3d9
|
|
@ -5,7 +5,8 @@ from __future__ import annotations
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from capabilities import require_capability
|
from capabilities import require_capability
|
||||||
from entity_archetypes import list_archetypes
|
from entity_archetypes import list_archetypes, validate_archetype_key
|
||||||
|
from services.archetype_starter_kit import get_starter_preview
|
||||||
from entity_fields.service import list_field_definitions
|
from entity_fields.service import list_field_definitions
|
||||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||||
from tenant_context import TenantContext
|
from tenant_context import TenantContext
|
||||||
|
|
@ -33,3 +34,20 @@ def get_archetype_field_definitions(
|
||||||
if not any(item["key"] == archetype_key for item in archetypes):
|
if not any(item["key"] == archetype_key for item in archetypes):
|
||||||
raise HTTPException(status_code=404, detail="Archetyp nicht gefunden")
|
raise HTTPException(status_code=404, detail="Archetyp nicht gefunden")
|
||||||
return list_field_definitions(archetype_key=archetype_key)
|
return list_field_definitions(archetype_key=archetype_key)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/{archetype_key}/starter-preview")
|
||||||
|
def get_archetype_starter_preview(
|
||||||
|
archetype_key: str,
|
||||||
|
method_profile_key: Optional[str] = Query(default=None),
|
||||||
|
ctx: TenantContext = Depends(require_capability("kairo.initiative.read")),
|
||||||
|
):
|
||||||
|
_ = ctx
|
||||||
|
try:
|
||||||
|
validate_archetype_key(entity_type="initiative", archetype_key=archetype_key)
|
||||||
|
except ValueError as exc:
|
||||||
|
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||||
|
return get_starter_preview(
|
||||||
|
archetype_key=archetype_key,
|
||||||
|
method_profile_key=method_profile_key,
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ class InitiativeCreateRequest(BaseModel):
|
||||||
priority: Literal["low", "normal", "high"] = "normal"
|
priority: Literal["low", "normal", "high"] = "normal"
|
||||||
owner_actor_id: Optional[str] = None
|
owner_actor_id: Optional[str] = None
|
||||||
method_profile_key: Optional[str] = Field(default=None, min_length=1)
|
method_profile_key: Optional[str] = Field(default=None, min_length=1)
|
||||||
|
apply_starter_kit: bool = True
|
||||||
|
|
||||||
|
|
||||||
class InitiativeUpdateRequest(BaseModel):
|
class InitiativeUpdateRequest(BaseModel):
|
||||||
|
|
@ -165,6 +166,7 @@ def create_initiative(
|
||||||
owner_actor_id=owner_actor_id,
|
owner_actor_id=owner_actor_id,
|
||||||
user_id=ctx.user_id,
|
user_id=ctx.user_id,
|
||||||
method_profile_key=body.method_profile_key,
|
method_profile_key=body.method_profile_key,
|
||||||
|
apply_starter_kit=body.apply_starter_kit,
|
||||||
)
|
)
|
||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"""Dogfooding R1 — Referenz-Vorhaben „Jinkendo Kairo“ (idempotent, Nicht-Prod).
|
"""Dogfooding R1 — Referenz-Vorhaben „Jinkendo Kairo“ (idempotent, Nicht-Prod).
|
||||||
|
|
||||||
Spiegelt Plan aus docs/product/ gemäß Kairo_Dogfooding_Mirror_Steering_v0.1.md.
|
DEPRECATED (2026-07-12): Nur Dev-Visualisierung. Produkt-Anlage über AP2.2a Starter-Kits.
|
||||||
|
Siehe Kairo_MVP_Execution_Plan_v0.2.md — nicht weiter ausbauen.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
|
||||||
370
backend/services/archetype_starter_kit.py
Normal file
370
backend/services/archetype_starter_kit.py
Normal file
|
|
@ -0,0 +1,370 @@
|
||||||
|
"""Archetyp Starter-Kits — AP2.2a (guided creation without Structure Builder)."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any, Optional
|
||||||
|
|
||||||
|
from entity_archetypes import resolve_default_method_key
|
||||||
|
|
||||||
|
# Stufe-A Archetypen mit automatischem Starter-Kit bei Anlage
|
||||||
|
STARTER_KIT_ARCHETYPES = frozenset(
|
||||||
|
{
|
||||||
|
"initiative.maturity_journey",
|
||||||
|
"initiative.linear_project",
|
||||||
|
"initiative.product",
|
||||||
|
"initiative.program",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
_GUIDANCE: dict[str, str] = {
|
||||||
|
"initiative.maturity_journey": (
|
||||||
|
"Aktuelle Stufe und heutige Übung steuern deinen nächsten Schritt."
|
||||||
|
),
|
||||||
|
"initiative.linear_project": (
|
||||||
|
"Nächster Schritt am kritischen Pfad — Abhängigkeiten im Plan-Graph."
|
||||||
|
),
|
||||||
|
"initiative.product": (
|
||||||
|
"Eingang triagieren, dann committete Actions — optional Sprint-Zeitbox (B3)."
|
||||||
|
),
|
||||||
|
"initiative.program": (
|
||||||
|
"Programm mit Abschluss — Gate-Horizont in Kontrolle."
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
_PROFILE_HINTS: dict[str, list[str]] = {
|
||||||
|
"initiative.maturity_journey": ["maturity.karate_kumite"],
|
||||||
|
"initiative.linear_project": [],
|
||||||
|
"initiative.product": ["product.kairo_dev"],
|
||||||
|
"initiative.program": [],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _find_by_title(items: list[dict[str, Any]], title: str) -> Optional[dict[str, Any]]:
|
||||||
|
for item in items:
|
||||||
|
if item.get("title") == title:
|
||||||
|
return item
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def supports_starter_kit(archetype_key: str) -> bool:
|
||||||
|
return archetype_key in STARTER_KIT_ARCHETYPES
|
||||||
|
|
||||||
|
|
||||||
|
def get_starter_preview(
|
||||||
|
*,
|
||||||
|
archetype_key: str,
|
||||||
|
method_profile_key: Optional[str] = None,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
method_key = resolve_default_method_key(archetype_key)
|
||||||
|
items: list[dict[str, Any]] = []
|
||||||
|
|
||||||
|
if archetype_key == "initiative.maturity_journey":
|
||||||
|
items = [
|
||||||
|
{"kind": "maturity_stage", "title": "Stufe 1 — Basis", "status": "active"},
|
||||||
|
{"kind": "maturity_stage", "title": "Stufe 2 — Aufbau", "status": "planned"},
|
||||||
|
{"kind": "maturity_stage", "title": "Stufe 3 — Ziel", "status": "planned"},
|
||||||
|
{"kind": "project", "title": "Training"},
|
||||||
|
{"kind": "recurring", "title": "Tägliche Übung"},
|
||||||
|
]
|
||||||
|
elif archetype_key == "initiative.linear_project":
|
||||||
|
items = [
|
||||||
|
{"kind": "milestone", "title": "G1 — Planung", "status": "active"},
|
||||||
|
{"kind": "milestone", "title": "G2 — Vorbereitung", "status": "planned"},
|
||||||
|
{"kind": "milestone", "title": "G3 — Umsetzung", "status": "planned"},
|
||||||
|
{"kind": "milestone", "title": "G4 — Abschluss", "status": "planned"},
|
||||||
|
{"kind": "project", "title": "Hauptpfad"},
|
||||||
|
{"kind": "project", "title": "Begleitung"},
|
||||||
|
]
|
||||||
|
elif archetype_key == "initiative.product":
|
||||||
|
items = [
|
||||||
|
{"kind": "milestone", "title": "Orientierung", "status": "active"},
|
||||||
|
{"kind": "milestone", "title": "Nächster Release-Horizont", "status": "planned"},
|
||||||
|
{"kind": "project", "title": "Entwicklung"},
|
||||||
|
{"kind": "project", "title": "Betrieb"},
|
||||||
|
{"kind": "backlog_item", "title": "Idee / Issue"},
|
||||||
|
{"kind": "hint", "title": "Optional: Sprint-Zeitbox unter Plan anlegen (B3)"},
|
||||||
|
]
|
||||||
|
elif archetype_key == "initiative.program":
|
||||||
|
items = [
|
||||||
|
{"kind": "milestone", "title": "Phase 1 — Start", "status": "active"},
|
||||||
|
{"kind": "milestone", "title": "Phase 2 — Lieferung", "status": "planned"},
|
||||||
|
{"kind": "milestone", "title": "Abschluss", "status": "planned"},
|
||||||
|
]
|
||||||
|
|
||||||
|
return {
|
||||||
|
"archetype_key": archetype_key,
|
||||||
|
"method_key": method_key,
|
||||||
|
"method_profile_key": method_profile_key,
|
||||||
|
"supported": supports_starter_kit(archetype_key),
|
||||||
|
"guidance": _GUIDANCE.get(archetype_key, ""),
|
||||||
|
"method_profile_hints": _PROFILE_HINTS.get(archetype_key, []),
|
||||||
|
"items": items,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def apply_starter_kit(
|
||||||
|
*,
|
||||||
|
tenant_id: str,
|
||||||
|
initiative_id: str,
|
||||||
|
archetype_key: str,
|
||||||
|
owner_actor_id: Optional[str] = None,
|
||||||
|
user_id: Optional[str] = None,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
"""Apply idempotent starter structure for supported Stufe-A archetypes."""
|
||||||
|
if not supports_starter_kit(archetype_key):
|
||||||
|
return {"applied": False, "reason": "unsupported_archetype"}
|
||||||
|
|
||||||
|
from services.roadmap import list_roadmap_items_for_initiative
|
||||||
|
|
||||||
|
existing = list_roadmap_items_for_initiative(
|
||||||
|
tenant_id=tenant_id, initiative_id=initiative_id
|
||||||
|
)
|
||||||
|
if existing:
|
||||||
|
return {"applied": False, "reason": "structure_exists"}
|
||||||
|
|
||||||
|
created: dict[str, list[str]] = {
|
||||||
|
"roadmap_items": [],
|
||||||
|
"projects": [],
|
||||||
|
"recurring": [],
|
||||||
|
"backlog_items": [],
|
||||||
|
}
|
||||||
|
|
||||||
|
if archetype_key == "initiative.maturity_journey":
|
||||||
|
created = _apply_a1(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
initiative_id=initiative_id,
|
||||||
|
user_id=user_id,
|
||||||
|
)
|
||||||
|
elif archetype_key == "initiative.linear_project":
|
||||||
|
created = _apply_a2(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
initiative_id=initiative_id,
|
||||||
|
user_id=user_id,
|
||||||
|
)
|
||||||
|
elif archetype_key == "initiative.product":
|
||||||
|
created = _apply_b2b(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
initiative_id=initiative_id,
|
||||||
|
user_id=user_id,
|
||||||
|
)
|
||||||
|
elif archetype_key == "initiative.program":
|
||||||
|
created = _apply_b2a(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
initiative_id=initiative_id,
|
||||||
|
user_id=user_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
from services.audit import log_audit
|
||||||
|
|
||||||
|
log_audit(
|
||||||
|
"initiative.starter_kit_applied",
|
||||||
|
user_id=user_id,
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
details={
|
||||||
|
"initiative_id": initiative_id,
|
||||||
|
"archetype_key": archetype_key,
|
||||||
|
"created": created,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"applied": True,
|
||||||
|
"archetype_key": archetype_key,
|
||||||
|
"guidance": _GUIDANCE.get(archetype_key, ""),
|
||||||
|
"created": created,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _apply_a1(
|
||||||
|
*,
|
||||||
|
tenant_id: str,
|
||||||
|
initiative_id: str,
|
||||||
|
user_id: Optional[str],
|
||||||
|
) -> dict[str, list[str]]:
|
||||||
|
from services.projects import create_project, list_projects_for_initiative
|
||||||
|
from services.recurring import create_recurring_element, list_recurring_for_initiative
|
||||||
|
from services.roadmap import create_roadmap_item
|
||||||
|
|
||||||
|
roadmap_ids: list[str] = []
|
||||||
|
stage_defs = [
|
||||||
|
("Stufe 1 — Basis", "active"),
|
||||||
|
("Stufe 2 — Aufbau", "planned"),
|
||||||
|
("Stufe 3 — Ziel", "planned"),
|
||||||
|
]
|
||||||
|
for index, (title, status) in enumerate(stage_defs):
|
||||||
|
item = create_roadmap_item(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
initiative_id=initiative_id,
|
||||||
|
title=title,
|
||||||
|
item_type="maturity_stage",
|
||||||
|
status=status, # type: ignore[arg-type]
|
||||||
|
sort_order=index * 10,
|
||||||
|
user_id=user_id,
|
||||||
|
)
|
||||||
|
roadmap_ids.append(item["id"])
|
||||||
|
|
||||||
|
projects = list_projects_for_initiative(tenant_id=tenant_id, initiative_id=initiative_id)
|
||||||
|
if not _find_by_title(projects, "Training"):
|
||||||
|
create_project(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
initiative_id=initiative_id,
|
||||||
|
title="Training",
|
||||||
|
description="Übungs- und Trainingsstruktur",
|
||||||
|
sort_order=0,
|
||||||
|
user_id=user_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
recurring = list_recurring_for_initiative(tenant_id=tenant_id, initiative_id=initiative_id)
|
||||||
|
if not _find_by_title(recurring, "Tägliche Übung"):
|
||||||
|
create_recurring_element(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
initiative_id=initiative_id,
|
||||||
|
title="Tägliche Übung",
|
||||||
|
description="Regelmäßige Übung für die aktuelle Reifegrad-Stufe",
|
||||||
|
interval_days=1,
|
||||||
|
user_id=user_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
return {"roadmap_items": roadmap_ids, "projects": ["Training"], "recurring": ["Tägliche Übung"]}
|
||||||
|
|
||||||
|
|
||||||
|
def _apply_a2(
|
||||||
|
*,
|
||||||
|
tenant_id: str,
|
||||||
|
initiative_id: str,
|
||||||
|
user_id: Optional[str],
|
||||||
|
) -> dict[str, list[str]]:
|
||||||
|
from services.projects import create_project, list_projects_for_initiative
|
||||||
|
from services.roadmap import add_dependency, create_roadmap_item
|
||||||
|
|
||||||
|
gate_titles = [
|
||||||
|
("G1 — Planung", "active"),
|
||||||
|
("G2 — Vorbereitung", "planned"),
|
||||||
|
("G3 — Umsetzung", "planned"),
|
||||||
|
("G4 — Abschluss", "planned"),
|
||||||
|
]
|
||||||
|
gate_ids: list[str] = []
|
||||||
|
for index, (title, status) in enumerate(gate_titles):
|
||||||
|
item = create_roadmap_item(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
initiative_id=initiative_id,
|
||||||
|
title=title,
|
||||||
|
item_type="milestone",
|
||||||
|
status=status, # type: ignore[arg-type]
|
||||||
|
sort_order=index * 10,
|
||||||
|
user_id=user_id,
|
||||||
|
)
|
||||||
|
gate_ids.append(item["id"])
|
||||||
|
|
||||||
|
for index in range(1, len(gate_ids)):
|
||||||
|
try:
|
||||||
|
add_dependency(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
from_item_id=gate_ids[index],
|
||||||
|
to_item_id=gate_ids[index - 1],
|
||||||
|
dependency_type="requires",
|
||||||
|
)
|
||||||
|
except ValueError as exc:
|
||||||
|
if "existiert bereits" not in str(exc):
|
||||||
|
raise
|
||||||
|
|
||||||
|
projects = list_projects_for_initiative(tenant_id=tenant_id, initiative_id=initiative_id)
|
||||||
|
for index, title in enumerate(["Hauptpfad", "Begleitung"]):
|
||||||
|
if not _find_by_title(projects, title):
|
||||||
|
create_project(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
initiative_id=initiative_id,
|
||||||
|
title=title,
|
||||||
|
description=f"Ist-Struktur — {title}",
|
||||||
|
sort_order=index,
|
||||||
|
user_id=user_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"roadmap_items": gate_ids,
|
||||||
|
"projects": ["Hauptpfad", "Begleitung"],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _apply_b2b(
|
||||||
|
*,
|
||||||
|
tenant_id: str,
|
||||||
|
initiative_id: str,
|
||||||
|
user_id: Optional[str],
|
||||||
|
) -> dict[str, list[str]]:
|
||||||
|
from services.backlog import create_backlog_item, list_backlog_for_initiative
|
||||||
|
from services.projects import create_project, list_projects_for_initiative
|
||||||
|
from services.roadmap import create_roadmap_item
|
||||||
|
|
||||||
|
roadmap_ids: list[str] = []
|
||||||
|
for index, (title, status) in enumerate(
|
||||||
|
[("Orientierung", "active"), ("Nächster Release-Horizont", "planned")]
|
||||||
|
):
|
||||||
|
item = create_roadmap_item(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
initiative_id=initiative_id,
|
||||||
|
title=title,
|
||||||
|
item_type="milestone",
|
||||||
|
status=status, # type: ignore[arg-type]
|
||||||
|
sort_order=index * 10,
|
||||||
|
user_id=user_id,
|
||||||
|
)
|
||||||
|
roadmap_ids.append(item["id"])
|
||||||
|
|
||||||
|
projects = list_projects_for_initiative(tenant_id=tenant_id, initiative_id=initiative_id)
|
||||||
|
for index, title in enumerate(["Entwicklung", "Betrieb"]):
|
||||||
|
if not _find_by_title(projects, title):
|
||||||
|
create_project(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
initiative_id=initiative_id,
|
||||||
|
title=title,
|
||||||
|
description=f"Ist-Struktur — {title}",
|
||||||
|
sort_order=index,
|
||||||
|
user_id=user_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
backlog = list_backlog_for_initiative(tenant_id=tenant_id, initiative_id=initiative_id)
|
||||||
|
if not _find_by_title(backlog, "Idee / Issue"):
|
||||||
|
create_backlog_item(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
initiative_id=initiative_id,
|
||||||
|
title="Idee / Issue",
|
||||||
|
description="Product Backlog — noch nicht committet",
|
||||||
|
user_id=user_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"roadmap_items": roadmap_ids,
|
||||||
|
"projects": ["Entwicklung", "Betrieb"],
|
||||||
|
"backlog_items": ["Idee / Issue"],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _apply_b2a(
|
||||||
|
*,
|
||||||
|
tenant_id: str,
|
||||||
|
initiative_id: str,
|
||||||
|
user_id: Optional[str],
|
||||||
|
) -> dict[str, list[str]]:
|
||||||
|
from services.roadmap import create_roadmap_item
|
||||||
|
|
||||||
|
roadmap_ids: list[str] = []
|
||||||
|
for index, (title, status) in enumerate(
|
||||||
|
[
|
||||||
|
("Phase 1 — Start", "active"),
|
||||||
|
("Phase 2 — Lieferung", "planned"),
|
||||||
|
("Abschluss", "planned"),
|
||||||
|
]
|
||||||
|
):
|
||||||
|
item = create_roadmap_item(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
initiative_id=initiative_id,
|
||||||
|
title=title,
|
||||||
|
item_type="milestone",
|
||||||
|
status=status, # type: ignore[arg-type]
|
||||||
|
sort_order=index * 10,
|
||||||
|
user_id=user_id,
|
||||||
|
)
|
||||||
|
roadmap_ids.append(item["id"])
|
||||||
|
|
||||||
|
return {"roadmap_items": roadmap_ids}
|
||||||
|
|
@ -74,6 +74,7 @@ def create_initiative(
|
||||||
priority: Priority = "normal",
|
priority: Priority = "normal",
|
||||||
user_id: Optional[str] = None,
|
user_id: Optional[str] = None,
|
||||||
method_profile_key: Optional[str] = None,
|
method_profile_key: Optional[str] = None,
|
||||||
|
apply_starter_kit: bool = True,
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
title = title.strip()
|
title = title.strip()
|
||||||
if not title:
|
if not title:
|
||||||
|
|
@ -138,6 +139,17 @@ def create_initiative(
|
||||||
archetype_key=archetype_key,
|
archetype_key=archetype_key,
|
||||||
method_profile_key=method_profile_key,
|
method_profile_key=method_profile_key,
|
||||||
)
|
)
|
||||||
|
if apply_starter_kit:
|
||||||
|
from services.archetype_starter_kit import apply_starter_kit
|
||||||
|
|
||||||
|
starter = apply_starter_kit(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
initiative_id=row["id"],
|
||||||
|
archetype_key=archetype_key,
|
||||||
|
owner_actor_id=owner_actor_id,
|
||||||
|
user_id=user_id,
|
||||||
|
)
|
||||||
|
row["starter_kit"] = starter
|
||||||
return row
|
return row
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
112
backend/tests/test_ap22a_starter_kit.py
Normal file
112
backend/tests/test_ap22a_starter_kit.py
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
"""AP2.2a — Archetyp Starter-Kits."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from tests.factories import provision_user_in_tenant
|
||||||
|
from tests.test_initiatives_actions import _auth, _login
|
||||||
|
|
||||||
|
|
||||||
|
def test_starter_preview_a2(client):
|
||||||
|
user = provision_user_in_tenant(tenant_role="member")
|
||||||
|
token = _login(client, user)
|
||||||
|
|
||||||
|
resp = client.get(
|
||||||
|
"/api/entity-archetypes/initiative.linear_project/starter-preview",
|
||||||
|
headers=_auth(token),
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
body = resp.json()
|
||||||
|
assert body["supported"] is True
|
||||||
|
assert body["method_key"] == "sequential_dependency"
|
||||||
|
assert any(item["kind"] == "milestone" for item in body["items"])
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_initiative_a1_applies_starter_kit(client):
|
||||||
|
user = provision_user_in_tenant(tenant_role="admin")
|
||||||
|
token = _login(client, user)
|
||||||
|
|
||||||
|
created = client.post(
|
||||||
|
"/api/initiatives",
|
||||||
|
json={
|
||||||
|
"title": "Test Spagat",
|
||||||
|
"archetype_key": "initiative.maturity_journey",
|
||||||
|
"apply_starter_kit": True,
|
||||||
|
},
|
||||||
|
headers=_auth(token),
|
||||||
|
)
|
||||||
|
assert created.status_code == 201
|
||||||
|
initiative_id = created.json()["id"]
|
||||||
|
assert created.json()["starter_kit"]["applied"] is True
|
||||||
|
|
||||||
|
roadmap = client.get(
|
||||||
|
f"/api/initiatives/{initiative_id}/roadmap/items",
|
||||||
|
headers=_auth(token),
|
||||||
|
)
|
||||||
|
assert roadmap.status_code == 200
|
||||||
|
titles = {item["title"] for item in roadmap.json()}
|
||||||
|
assert "Stufe 1 — Basis" in titles
|
||||||
|
|
||||||
|
recurring = client.get(
|
||||||
|
f"/api/initiatives/{initiative_id}/recurring",
|
||||||
|
headers=_auth(token),
|
||||||
|
)
|
||||||
|
assert recurring.status_code == 200
|
||||||
|
assert any(r["title"] == "Tägliche Übung" for r in recurring.json())
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_initiative_b2b_starter_kit(client):
|
||||||
|
user = provision_user_in_tenant(tenant_role="admin")
|
||||||
|
token = _login(client, user)
|
||||||
|
|
||||||
|
created = client.post(
|
||||||
|
"/api/initiatives",
|
||||||
|
json={
|
||||||
|
"title": "Test Product",
|
||||||
|
"archetype_key": "initiative.product",
|
||||||
|
},
|
||||||
|
headers=_auth(token),
|
||||||
|
)
|
||||||
|
assert created.status_code == 201
|
||||||
|
initiative_id = created.json()["id"]
|
||||||
|
|
||||||
|
backlog = client.get(
|
||||||
|
f"/api/initiatives/{initiative_id}/backlog",
|
||||||
|
headers=_auth(token),
|
||||||
|
)
|
||||||
|
assert backlog.status_code == 200
|
||||||
|
assert any(b["title"] == "Idee / Issue" for b in backlog.json())
|
||||||
|
|
||||||
|
projects = client.get(
|
||||||
|
f"/api/initiatives/{initiative_id}/projects",
|
||||||
|
headers=_auth(token),
|
||||||
|
)
|
||||||
|
assert projects.status_code == 200
|
||||||
|
titles = {p["title"] for p in projects.json()}
|
||||||
|
assert "Entwicklung" in titles
|
||||||
|
assert "Betrieb" in titles
|
||||||
|
|
||||||
|
|
||||||
|
def test_starter_kit_skipped_when_structure_exists(client):
|
||||||
|
user = provision_user_in_tenant(tenant_role="admin")
|
||||||
|
token = _login(client, user)
|
||||||
|
|
||||||
|
created = client.post(
|
||||||
|
"/api/initiatives",
|
||||||
|
json={
|
||||||
|
"title": "Kit Once",
|
||||||
|
"archetype_key": "initiative.linear_project",
|
||||||
|
},
|
||||||
|
headers=_auth(token),
|
||||||
|
)
|
||||||
|
initiative_id = created.json()["id"]
|
||||||
|
assert created.json()["starter_kit"]["applied"] is True
|
||||||
|
|
||||||
|
from services.archetype_starter_kit import apply_starter_kit
|
||||||
|
|
||||||
|
again = apply_starter_kit(
|
||||||
|
tenant_id=user["tenant_id"],
|
||||||
|
initiative_id=initiative_id,
|
||||||
|
archetype_key="initiative.linear_project",
|
||||||
|
)
|
||||||
|
assert again["applied"] is False
|
||||||
|
assert again["reason"] == "structure_exists"
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
APP_VERSION = "0.19.0-ap2.0f"
|
APP_VERSION = "0.20.0-ap2.2a"
|
||||||
DB_SCHEMA_VERSION = "025"
|
DB_SCHEMA_VERSION = "025"
|
||||||
APP_NAME = "jinkendo-kairo"
|
APP_NAME = "jinkendo-kairo"
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
**Vision:** `Kairo_Vision_and_Product_Direction_v0.2.md`
|
**Vision:** `Kairo_Vision_and_Product_Direction_v0.2.md`
|
||||||
**MVP-Nordstern:** `Kairo_MVP_Definition_v0.3.md` (führend für Abnahfe)
|
**MVP-Nordstern:** `Kairo_MVP_Definition_v0.3.md` (führend für Abnahfe)
|
||||||
**Ist-Stand:** `Kairo_Implementation_Truth_Table_v0.1.md`
|
**Ist-Stand:** `Kairo_Implementation_Truth_Table_v0.1.md`
|
||||||
**Review & Nächste Schritte:** `Kairo_Status_Review_and_Next_Steps_v0.1.md`
|
**Review & Nächste Schritte:** `Kairo_Status_Review_and_Next_Steps_v0.2.md`
|
||||||
**Dogfooding:** `Kairo_Dogfooding_Mirror_Steering_v0.1.md`
|
**Execution Plan:** `Kairo_MVP_Execution_Plan_v0.2.md` (führend ab 2026-07-12)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -172,25 +172,21 @@ Phase N Integration Gitea/MCP nach AP1.7
|
||||||
|
|
||||||
## 4. Nächste Pakete (verbindliche Reihenfolge — PO 2026-07-06)
|
## 4. Nächste Pakete (verbindliche Reihenfolge — PO 2026-07-06)
|
||||||
|
|
||||||
### 4.0 Abnahme-Reihenfolge (Stand 2026-07-11 — Review)
|
### 4.0 Nächste Schritte (Stand 2026-07-12 — Kurskorrektur)
|
||||||
|
|
||||||
Siehe **`Kairo_Status_Review_and_Next_Steps_v0.1.md` §5** für vollständige Roadmap.
|
**Führend:** `Kairo_MVP_Execution_Plan_v0.2.md` · `Kairo_Status_Review_and_Next_Steps_v0.2.md`
|
||||||
|
|
||||||
| Phase | Paket | Status | Begründung |
|
| Phase | Paket | Status | Begründung |
|
||||||
|-------|-------|--------|------------|
|
|-------|-------|--------|------------|
|
||||||
| D0 | DOC-Sync (Truth Table, Gap, Review) | ✓ | eine Wahrheit |
|
| — | Infrastruktur AP1.9c, AP1.16, AP2.0d, AP1.7, AP2.0f | ✓ Code | Steering-Motor |
|
||||||
| D1 | Dogfooding R1 — Kairo-Jinkendo in Kairo | **◐ Seed R2** | B2b-Validation; Pi nach Deploy |
|
| **1** | **AP2.2a** Archetyp-Anlage + Starter-Kits | **→ Code** | Referenz-Vorhaben ohne Seed |
|
||||||
| 1 | AP1.9c Cockpit-Signale | **◐ Code** | Portfolio-Kacheln via Attention |
|
| 2 | AP1.9d Methoden-Default-UI | offen | Anti-Todo-Wand |
|
||||||
| 2 | AP1.16a–b Execution-Graph (Schema + Engine) | **◐ Code** | Remote-Verifikation nach Deploy |
|
| 3 | AP2.2b–e End-to-End A1, A2, B2b, B3 | offen | MVP Stufe A produktiv |
|
||||||
| 3 | AP2.0d Next-Action-Strategien | **◐ Code** | Remote-Verifikation nach Deploy |
|
| 4 | AP1.7b Op-API Pflege-Parität | offen | Vibe-Coder |
|
||||||
| 4 | AP1.16c–d Plan-Outline-Kanten + Planning Debt | **◐ Code** | Remote-Verifikation nach Deploy |
|
| 5 | AP2.1 Validation (A1+A2+B2b+D1) | offen | nach Phase 3 |
|
||||||
| 5 | Dogfooding R2 — Ist + Gitea-Evidence | **→ nächstes** | Seed sync + manuelle Abnahfe |
|
| 6 | Gitea/MCP Schicht 4 | deferred | nach AP2.1 |
|
||||||
| 6 | AP1.7 Operational Actor API | **◐ Code** | `/api/operational/` + Service Tokens |
|
|
||||||
| 7 | AP2.0f work_cycle (B3 minimal) | **◐ Code** | Sprint-Zeitbox; Remote-Verifikation nach Deploy |
|
|
||||||
| 8 | AP1.7 Operational API | offen | MCP-Voraussetzung |
|
|
||||||
| 9 | Gitea-Webhook + MCP | deferred | Schicht 4 |
|
|
||||||
|
|
||||||
**Erledigt (Review-Queue):** AP1.6b ✓
|
**Deprecated:** Dogfooding-Seed als Implementierungs-Hebel (nur Dev-Visualisierung).
|
||||||
|
|
||||||
### AP1.5 — Hierarchie & Ist-Ebene ✓
|
### AP1.5 — Hierarchie & Ist-Ebene ✓
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
# Jinkendo Kairo
|
# Jinkendo Kairo
|
||||||
## Dogfooding — Spiegel-Steuerung für Kairo-Jinkendo v0.1
|
## Dogfooding — Spiegel-Steuerung für Kairo-Jinkendo v0.1
|
||||||
|
|
||||||
**Status:** Betriebskonzept (Phase 1 — manuell)
|
> **DEPRECATED als Implementierungs-Hebel (2026-07-12).** Nur optional Dev-Visualisierung (`seed_004`, Nicht-Prod).
|
||||||
**Stand:** 2026-07-11
|
> **Produkt-Priorität:** `Kairo_MVP_Execution_Plan_v0.2.md` — Referenz-Vorhaben per UI/AP2.2a anlegen.
|
||||||
|
|
||||||
|
**Status:** Betriebskonzept (historisch)
|
||||||
|
**Stand:** 2026-07-11 (Seed deprecated 2026-07-12)
|
||||||
**Auslöser:** Kairo-Jinkendo als Referenz-Vorhaben B2b in Kairo führen; Plan bleibt in Git/Docs, Kairo spiegelt Ist + Fortschritt
|
**Auslöser:** Kairo-Jinkendo als Referenz-Vorhaben B2b in Kairo führen; Plan bleibt in Git/Docs, Kairo spiegelt Ist + Fortschritt
|
||||||
**Bezug:** `Kairo_MVP_Definition_v0.3.md` §8 (B2b), `ADP_Archetype_and_Method_Catalog_v0.2.md` (`product.kairo_dev`), `Kairo_Status_Review_and_Next_Steps_v0.1.md`
|
**Bezug:** `Kairo_MVP_Definition_v0.3.md` §8 (B2b), `ADP_Archetype_and_Method_Catalog_v0.2.md` (`product.kairo_dev`), `Kairo_Status_Review_and_Next_Steps_v0.1.md`
|
||||||
|
|
||||||
|
|
@ -75,16 +78,16 @@ Gates = **Zielzustände** entlang der **bereits erledigten und offenen Phasen**
|
||||||
|
|
||||||
Vorschlag **8 Gates** (sequenziell, `requires`-Kanten):
|
Vorschlag **8 Gates** (sequenziell, `requires`-Kanten):
|
||||||
|
|
||||||
| # | Gate-Titel | Status (2026-07-11) | Kriterien (Beispiele) |
|
| # | Gate-Titel | Status (2026-07-12) | Kriterien (Beispiele) |
|
||||||
|---|------------|---------------------|------------------------|
|
|---|------------|---------------------|------------------------|
|
||||||
| G1 | Foundation AP0 | **reached** | Tenant, Actor, Auth, OM-Tabellen |
|
| G1 | Foundation AP0 | **reached** | Tenant, Actor, Auth, OM-Tabellen |
|
||||||
| G2 | IA & Steering Skeleton | **reached** | AP1.2c, AP1.0, Snapshot |
|
| G2 | IA & Steering Skeleton | **reached** | AP1.2c, AP1.0, Snapshot |
|
||||||
| G3 | Gates & Checkliste Backend | **reached** | AP1.4/4b, Verify API |
|
| G3 | Gates & Checkliste Backend | **reached** | AP1.4/4b, Verify API |
|
||||||
| G4 | Ist-Hierarchie & Plan/Ist | **reached** | AP1.5/5c, AP1.6, AP1.14 |
|
| G4 | Ist-Hierarchie & Plan/Ist | **reached** | AP1.5/5c, AP1.6, AP1.14 |
|
||||||
| G5 | PM Work Modes & Plan-Outline | **active** | AP1.9a/9c ✓, AP1.12 ◐, AP1.16 ◐ |
|
| G5 | PM Work Modes & Plan-Outline | **active** | AP1.9a/9c ✓, AP1.12 ◐, AP1.16 ✓ |
|
||||||
| G6 | Archetyp-Steuerung MVP | **active** | AP2.0 ◐, AP2.0d ✓, Execution-Graph ✓ |
|
| G6 | Archetyp-Steuerung MVP | **reached** | AP2.0 ✓, AP1.7 ✓, AP2.0d ✓, AP2.0f ✓ |
|
||||||
| G7 | MVP-Abnahfe B2b | **planned** | Validation, Leitfrage, Cockpit-Signale |
|
| G7 | MVP-Abnahfe B2b | **active** | AP2.1 Validation, Leitfrage, Cockpit |
|
||||||
| G8 | Agent & Integration | **planned** | AP1.7, Gitea-Webhook optional |
|
| G8 | Agent & Integration | **planned** | Gitea-Webhook, MCP (AP1.7 ✓) |
|
||||||
|
|
||||||
**Verify-Regel:** Gate auf `reached` nur wenn Kriterien erfüllt (AP1.4b) — rückwirkend für G1–G4 mit Evidence „Completion Report / Commit-Spanne“.
|
**Verify-Regel:** Gate auf `reached` nur wenn Kriterien erfüllt (AP1.4b) — rückwirkend für G1–G4 mit Evidence „Completion Report / Commit-Spanne“.
|
||||||
|
|
||||||
|
|
@ -104,17 +107,22 @@ Vorschlag **8 Gates** (sequenziell, `requires`-Kanten):
|
||||||
| AP1.8a Portfolio-Rang | G5 | Commit `a19c6ab` |
|
| AP1.8a Portfolio-Rang | G5 | Commit `a19c6ab` |
|
||||||
| AP1.15a–c Zielzustands-Designer | G4/G5 | Commits `0c2ca4a`…`d7aefed` |
|
| AP1.15a–c Zielzustands-Designer | G4/G5 | Commits `0c2ca4a`…`d7aefed` |
|
||||||
| AP2.0 Archetyp-Slice | G6 | Commit `3bd9832` ff. |
|
| AP2.0 Archetyp-Slice | G6 | Commit `3bd9832` ff. |
|
||||||
|
| AP1.9c Cockpit-Signale | G5 | Commit `b9bfa9e` |
|
||||||
|
| AP1.16 Execution-Graph | G6 | Commits `1166a0c`…`b9bfa9e` |
|
||||||
|
| AP2.0d Next-Action-Strategien | G6 | Commit `284b9d5` |
|
||||||
|
| AP1.7 Operational Actor API | G6 | Commit `5dc372c` |
|
||||||
|
| AP2.0f work_cycle / Sprint | G6 | Commit `d1bc725` |
|
||||||
|
| Dogfooding R2 — Ist gespiegelt | G7 | Commit `a097a82` |
|
||||||
|
| DOC-Sync (Status-Review) | G6 | erledigt |
|
||||||
|
|
||||||
### 4.2 Offen → Action `open` / `in_progress`
|
### 4.2 Offen → Action `open` / `in_progress`
|
||||||
|
|
||||||
| Action-Titel | Gate | Priorität |
|
| Action-Titel | Gate | Priorität |
|
||||||
|--------------|------|-----------|
|
|--------------|------|-----------|
|
||||||
| AP1.9c Cockpit-Signale | G5 | **done** (`b9bfa9e`) |
|
| AP2.1 B2b Validation (Leitfrage-Test) | G7 | **in_progress** — PO-Gate |
|
||||||
| AP1.16 Execution-Graph | G6 | **done** (`1166a0c`…`b9bfa9e`) |
|
| AP1.16c–d Plan-Outline AP-Kanten | G5 | open |
|
||||||
| AP2.0d Next-Action-Strategien | G6 | **done** (`284b9d5`) |
|
|
||||||
| Dogfooding R2 — Ist pflegen | G6 | **laufend** |
|
**Zeitbox:** `Iteration — MVP B2b Slice` (active) — AP2.1 zugeordnet.
|
||||||
| AP1.7 Operational API | G8 | nach Validation |
|
|
||||||
| DOC-Sync (dieser Slice) | G6 | erledigt mit Commit |
|
|
||||||
|
|
||||||
**Zuordnung:** `roadmap_item_id` = aktuelles Gate; `project_id` = Backend/Frontend/Docs.
|
**Zuordnung:** `roadmap_item_id` = aktuelles Gate; `project_id` = Backend/Frontend/Docs.
|
||||||
|
|
||||||
|
|
@ -222,9 +230,10 @@ Auf dem **Pi-Deploy** (nach Push auf `develop`):
|
||||||
**Manuell prüfen** in Kairo UI:
|
**Manuell prüfen** in Kairo UI:
|
||||||
|
|
||||||
- [ ] Initiative „Jinkendo Kairo“ sichtbar (`initiative.product`, Profil `product.kairo_dev`)
|
- [ ] Initiative „Jinkendo Kairo“ sichtbar (`initiative.product`, Profil `product.kairo_dev`)
|
||||||
- [ ] 4 Projects, 8 Gates (G1–G4 `reached`, G5–G6 `active`)
|
- [ ] 4 Projects, 8 Gates (G1–G6 `reached`, G7 `active`)
|
||||||
- [ ] Actions offen: Dogfooding R2, AP1.7, AP2.0f
|
- [ ] Aktive Zeitbox „Iteration — MVP B2b Slice“ in Kontrolle
|
||||||
- [ ] Actions done: AP1.9c, AP1.16, AP2.0d (Evidence mit Gitea-Links)
|
- [ ] Action in_progress: AP2.1 B2b Validation
|
||||||
|
- [ ] Actions done: AP1.9c, AP1.16, AP2.0d, AP1.7, AP2.0f (Evidence mit Gitea-Links)
|
||||||
- [ ] Evidence mit Gitea-Commit-Links (z. B. `b85a6ec`, `a19c6ab`)
|
- [ ] Evidence mit Gitea-Commit-Links (z. B. `b85a6ec`, `a19c6ab`)
|
||||||
- [ ] Cockpit: Portfolio-Rang #1
|
- [ ] Cockpit: Portfolio-Rang #1
|
||||||
- [ ] Kontrolle: Leitfrage-Test — „Was ist als Nächstes dran?“
|
- [ ] Kontrolle: Leitfrage-Test — „Was ist als Nächstes dran?“
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,8 @@ Verhindert, dass Zielbild-Dokumente als Ist-Stand gelesen werden.
|
||||||
| Initiative Archetypes | ◐ | Migration 016, Registry AP2.0b |
|
| Initiative Archetypes | ◐ | Migration 016, Registry AP2.0b |
|
||||||
| Method Profiles (Code-Seeds) | ◐ | `product.kairo_dev`, Kumite, Buch — AP2.0b |
|
| Method Profiles (Code-Seeds) | ◐ | `product.kairo_dev`, Kumite, Buch — AP2.0b |
|
||||||
| Execution Graph Engine | ◐ | AP1.16b; API `/execution/graph-state` |
|
| Execution Graph Engine | ◐ | AP1.16b; API `/execution/graph-state` |
|
||||||
| Planning Debt (Attention) | ◐ | AP1.16d: Attention + Cockpit-Kacheln AP1.9c |
|
| Planning Debt (Attention) | ◐ | AP1.16d: Attention + Cockpit-Kacheln AP1.9c ✓ |
|
||||||
| `work_cycle` / Sprint | ◐ | AP2.0f Code: RoadmapItem + actions.work_cycle_id; Remote-Verifikation |
|
| `work_cycle` / Sprint | ✓ | AP2.0f: RoadmapItem + actions.work_cycle_id; Kontrolle zeigt aktive Zeitbox |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -76,7 +76,7 @@ Verhindert, dass Zielbild-Dokumente als Ist-Stand gelesen werden.
|
||||||
|---------|-------|-----------|
|
|---------|-------|-----------|
|
||||||
| steering_contexts (009) | ✓ | Lifecycle, method_key |
|
| steering_contexts (009) | ✓ | Lifecycle, method_key |
|
||||||
| backend/steering/ lifecycle | ✓ | |
|
| backend/steering/ lifecycle | ✓ | |
|
||||||
| Signal Engine | ◐ | Regeln begrenzt; Cockpit-Kacheln offen AP1.9c |
|
| Signal Engine | ◐ | Regeln begrenzt; Cockpit-Kacheln AP1.9c ✓ |
|
||||||
| Method Registry | ◐ | AP2.0a: Stubs inkl. `continuous_product`, `program_delivery`, …; 2 Strategien aktiv |
|
| Method Registry | ◐ | AP2.0a: Stubs inkl. `continuous_product`, `program_delivery`, …; 2 Strategien aktiv |
|
||||||
| Archetyp-/Methoden-Katalog PO | ✓ | ADP v0.2 + MVP v0.3 |
|
| Archetyp-/Methoden-Katalog PO | ✓ | ADP v0.2 + MVP v0.3 |
|
||||||
| NextActionCandidate | ◐ | API + Widget; `reason_code` AP2.0c/d; Strategien nutzen `ready_actions` (AP2.0d) |
|
| NextActionCandidate | ◐ | API + Widget; `reason_code` AP2.0c/d; Strategien nutzen `ready_actions` (AP2.0d) |
|
||||||
|
|
@ -142,6 +142,18 @@ Verhindert, dass Zielbild-Dokumente als Ist-Stand gelesen werden.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Referenz-Archetypen End-to-End (MVP Stufe A)
|
||||||
|
|
||||||
|
| Archetyp | Anlage+Kit | Struktur pflegen | Kontrolle | Op-API | Paket |
|
||||||
|
|----------|------------|------------------|-----------|--------|-------|
|
||||||
|
| A1 Reifegrad | ◐ AP2.2a | ◐ | ◐ | ◐ | AP2.2c + AP2.0e |
|
||||||
|
| A2 Linear | ◐ AP2.2a | ◐ | ◐ | ◐ | AP2.2b |
|
||||||
|
| B2b Product | ◐ AP2.2a | ◐ | ◐ | ◐ | AP2.2d |
|
||||||
|
| B3 Sprint-Profil | ◐ | ◐ | ◐ | ◐ | AP2.2d |
|
||||||
|
| B2a Programm | ◐ AP2.2a | ◐ | ◐ | ◐ | AP2.2e |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Archetyp / MVP v0.3
|
## Archetyp / MVP v0.3
|
||||||
|
|
||||||
| Element | Stand | Anmerkung |
|
| Element | Stand | Anmerkung |
|
||||||
|
|
@ -151,12 +163,13 @@ Verhindert, dass Zielbild-Dokumente als Ist-Stand gelesen werden.
|
||||||
| Default-Methode bei Anlage | ◐ | AP2.0b |
|
| Default-Methode bei Anlage | ◐ | AP2.0b |
|
||||||
| Next-Action program_delivery | ◐ | Strategie registriert |
|
| Next-Action program_delivery | ◐ | Strategie registriert |
|
||||||
| Next-Action continuous_product | ◐ | Strategie registriert |
|
| Next-Action continuous_product | ◐ | Strategie registriert |
|
||||||
| maturity / sequential / queue / recurring Strategien | ◐ | AP2.0d Code; Remote-Verifikation nach Deploy |
|
| maturity / sequential / queue / recurring Strategien | ✓ | AP2.0d; pytest + Deploy |
|
||||||
| Referenz-Ausprägung product.kairo_dev | ◐ | Code-Seed; Dogfooding manuell |
|
| Referenz-Ausprägungen (Kumite, Buch, Kairo) | ◐ | Code-Registry; Nutzer wählt bei Anlage |
|
||||||
| MVP-Abnahfe Stufe A validiert | ✗ | AP0.10d / AP2.1 offen |
|
| Archetyp Starter-Kits | ◐ | AP2.2a |
|
||||||
| Operational Actor API | ◐ | AP1.7 Code: `/api/operational/` + Service Tokens; Remote-Verifikation |
|
| MVP-Abnahfe Stufe A validiert | ✗ | AP2.1 nach AP2.2b–e |
|
||||||
| Actor Service Token | ◐ | AP1.7c; Tenant-scoped, capability-gebunden |
|
| Operational Actor API | ✓ | AP1.7: `/api/operational/` + Service Tokens |
|
||||||
| MCP produktiv | ✗ | nach AP1.7 |
|
| Actor Service Token | ✓ | AP1.7c; Tenant-scoped, capability-gebunden |
|
||||||
|
| MCP produktiv | ✗ | nach AP2.1 Go |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -203,13 +216,10 @@ Details: `Kairo_Status_Review_and_Next_Steps_v0.1.md` §2.1
|
||||||
|
|
||||||
| AP | Erwartung |
|
| AP | Erwartung |
|
||||||
|----|-----------|
|
|----|-----------|
|
||||||
| AP1.16a–b | Action deps, Execution Engine ✗→◐ (Deploy) |
|
| AP2.2a | Starter-Kits ◐→✓ |
|
||||||
| AP1.16c–d | Outline-Kanten, Planning Debt ✗→◐ |
|
| AP2.2b–e | Referenz-Archetypen End-to-End ◐→✓ |
|
||||||
| AP1.9c | Cockpit-Signale ◐→✓ |
|
| AP2.1 | MVP-Abnahfe ✗→✓ |
|
||||||
| AP2.0d | Strategien ◐ Code |
|
| AP1.7b | Op-API Parität |
|
||||||
| Dogfooding R1 | Referenz-Vorhaben in Alltag ◐ | Seed R2 sync nach Deploy |
|
|
||||||
| AP2.0f | work_cycle ◐ Code |
|
|
||||||
| AP1.7 | Operational API ◐ Code |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
162
docs/product/Kairo_MVP_Execution_Plan_v0.2.md
Normal file
162
docs/product/Kairo_MVP_Execution_Plan_v0.2.md
Normal file
|
|
@ -0,0 +1,162 @@
|
||||||
|
# Jinkendo Kairo
|
||||||
|
## MVP Execution Plan v0.2
|
||||||
|
|
||||||
|
**Status:** PO-Kurskorrektur — **führend für Implementierung ab 2026-07-12**
|
||||||
|
**Stand:** 2026-07-12
|
||||||
|
**Ersetzt als Priorisierung:** Dogfooding-Seed als Implementierungs-Hebel; Status-Review §5 (Dogfooding-first)
|
||||||
|
**Bezug:** `Kairo_MVP_Definition_v0.3.md` §5–9, `ADP_Archetype_and_Method_Catalog_v0.2.md` §3, `Kairo_Corrected_MVP_Roadmap_v0.2.md` (AP-Historie)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Nordstern (unverändert)
|
||||||
|
|
||||||
|
Kairo ist MVP-nah, wenn ein Nutzer **mehrere typische Vorhabenarten** (Referenz-Portfolio) **erfassen, steuern und nachvollziehen** kann — archetyp- und methodengebunden, ohne Todo-Explosion.
|
||||||
|
|
||||||
|
**Nicht MVP-Ziel:** Kairo-Entwicklungsstand in Kairo spiegeln (Dogfooding-Seed). Das war nur Dev-Visualisierung.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Referenz-Portfolio — Checkliste pro Archetyp
|
||||||
|
|
||||||
|
Legende: **Anlage** · **Struktur** · **Ist** · **Kontrolle** · **UI-Default** · **Op-API**
|
||||||
|
|
||||||
|
| ID | Archetyp | Beispiel | Methode | Stufe | Anlage | Struktur | Ist | Kontrolle | UI-Default | Op-API |
|
||||||
|
|----|----------|----------|---------|-------|--------|----------|-----|-----------|------------|--------|
|
||||||
|
| A1 | `initiative.maturity_journey` | Spagat / Kumite | `maturity_progression` | **A** | ◐ | ◐ | ◐ | ◐ | ✗ | ◐ |
|
||||||
|
| A2 | `initiative.linear_project` | Neue Küche | `sequential_dependency` | **A** | ◐ | ◐ | ◐ | ◐ | ✗ | ◐ |
|
||||||
|
| A3 | `initiative.recurring_program` | Haus in Ordnung | `recurring_control` | B | ◐ | ✗ | ◐ | ◐ | ✗ | ◐ |
|
||||||
|
| B1 | `initiative.support_queue` | Tickets | `queue_pull` | B | ◐ | ✗ | ◐ | ◐ | ✗ | ◐ |
|
||||||
|
| B2a | `initiative.program` | Release-Programm | `program_delivery` | A* | ◐ | ◐ | ◐ | ◐ | ✗ | ◐ |
|
||||||
|
| B2b | `initiative.product` | Product-Betrieb | `continuous_product` | **A** | ◐ | ◐ | ◐ | ◐ | ✗ | ◐ |
|
||||||
|
| B3 | *(Profil auf B2)* | Sprint-Zeitbox | `agile_iteration` | **A min** | ◐ | ◐ | ◐ | ◐ | ✗ | ◐ |
|
||||||
|
| D1 | `initiative.content_project` | Buch schreiben | `chapter_based_progression` | B | ◐ | ✗ | ◐ | ◐ | ✗ | ◐ |
|
||||||
|
| C1 | `initiative.dispute_case` | Miterstreit | `dispute_procedure` | C | Katalog | — | — | — | — | — |
|
||||||
|
|
||||||
|
\* B2a in ADP Stufe A; MVP v0.3 §4 nennt explizit A1, A2, B2b + B3 — B2a im Validation-Slice mitdenken.
|
||||||
|
|
||||||
|
**Ausprägungen (Code-Seeds):** `maturity.karate_kumite`, `content.book_writing`, `product.kairo_dev` — Vorlagen, **kein** Ersatz für Nutzer-Anlage.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Was technisch da ist vs. was fehlt
|
||||||
|
|
||||||
|
### 3.1 Vorhanden (Infrastruktur — nicht wiederholen)
|
||||||
|
|
||||||
|
- OM, Gates, Graph Engine, Plan-Outline, Journey, Plan/Ist-Diff
|
||||||
|
- Archetyp-Registry, EFS, Profil-Modal (AP1.10c)
|
||||||
|
- PM Work Modes Shell (AP1.9a), Cockpit-Signale (AP1.9c)
|
||||||
|
- Next-Action-Strategien registriert (AP2.0d)
|
||||||
|
- Execution-Graph / `ready_actions` (AP1.16)
|
||||||
|
- `work_cycle` + `actions.work_cycle_id` (AP2.0f)
|
||||||
|
- Operational Actor API + Service Tokens (AP1.7)
|
||||||
|
|
||||||
|
### 3.2 Produkt-Lücken (MVP-kritisch)
|
||||||
|
|
||||||
|
| Lücke | Bedeutung | Paket |
|
||||||
|
|-------|-----------|-------|
|
||||||
|
| Archetyp-geführte Anlage | Nutzer wählt Typ → sinnvolle Startstruktur + Guidance | **AP2.2a** |
|
||||||
|
| Methoden-Default-UI | Ausführen/Kontrolle zeigt Next Action, nicht Gesamtliste | **AP1.9d** |
|
||||||
|
| A1 Stufenwechsel + Recurring | AP2.0e: Routine wechselt bei `maturity_stage` reached | **AP2.0e** |
|
||||||
|
| A2 kritischer Pfad | Kontrolle aus sequential + Graph Read Model | **AP2.2b** |
|
||||||
|
| B2b Eingang → Commit | Product Backlog vs. Sprint-Backlog sichtbar getrennt | **AP2.2d** |
|
||||||
|
| B3 Sprint-Default | Aktiver `work_cycle`; Ausführen = Sprint-Items | **AP2.2d** |
|
||||||
|
| `chapter` RoadmapItem | D1 Plan-Schicht | **AP2.2f** (Stufe B) |
|
||||||
|
| Structure Builder (voll) | Automatische Tiefenplanung | **deferred** — Starter-Kits stattdessen |
|
||||||
|
| Op-API Parität | Agent pflegt dasselbe wie UI | **AP1.7b** |
|
||||||
|
| Referenz-Validation | AP2.1 über A1, A2, B2b (+ B3), D1 | **AP2.1** |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Implementierungsfolge (korrigiert)
|
||||||
|
|
||||||
|
```text
|
||||||
|
Phase 0 DOC + Kurskorrektur (dieses Dokument) ← jetzt
|
||||||
|
Phase 1 AP2.2a Archetyp-geführte Anlage + Starter-Kits ← NÄCHSTES CODE
|
||||||
|
Phase 2 AP1.9d Methoden-Default-Ansichten (Anti-Todo-Wand) parallel möglich
|
||||||
|
Phase 3 AP2.2b A2 Linear End-to-End
|
||||||
|
AP2.2c A1 Reifegrad + AP2.0e
|
||||||
|
AP2.2d B2b Product + B3 Sprint
|
||||||
|
AP2.2e B2a Programm (optional vor AP2.1)
|
||||||
|
Phase 4 AP1.7b Operational API — Pflege-Parität
|
||||||
|
Phase 5 AP2.1 Validation Report v0.3 (alle Stufe-A-Szenarien)
|
||||||
|
Phase 6 AP2.2f Stufe B: A3, B1, D1
|
||||||
|
Phase 7 Schicht 4: Gitea-Webhook, MCP (nach AP2.1 Go)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Eingefroren / deprecated:**
|
||||||
|
|
||||||
|
- `seed_004_dogfooding_*` — nur Dev-Visualisierung, **kein** Produkt-AP
|
||||||
|
- Dogfooding als „nächster strategischer Hebel“ in Roadmaps
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. AP2.2 — Referenz-Vorhaben (Paketübersicht)
|
||||||
|
|
||||||
|
| Paket | Ziel | DoD-Kern |
|
||||||
|
|-------|------|----------|
|
||||||
|
| **AP2.2a** | Geführte Anlage | Archetyp-Wahl → Starter-Kit + 1-Satz-Guidance; Ausprägung wählbar |
|
||||||
|
| **AP2.2b** | A2 Küche | Gate-Kette/Graph anlegbar; Kontrolle: nächster ready Schritt + Begründung |
|
||||||
|
| **AP2.2c** | A1 Spagat/Kumite | `maturity_stage` + Recurring; AP2.0e bei Stufenübergang |
|
||||||
|
| **AP2.2d** | B2b + B3 | Eingang, Gates, optional aktive Zeitbox; Sprint-Backlog in Ausführen |
|
||||||
|
| **AP2.2e** | B2a Programm | `program_delivery`, Abschluss-Lifecycle, Gate-Horizont |
|
||||||
|
| **AP2.2f** | D1 Buch (B) | `chapter` item_type; nächstes Kapitel in Kontrolle |
|
||||||
|
|
||||||
|
Assignment AP2.2a: `docs/sprints/Sprint1_AP2_2a_Archetype_Guided_Creation_Assignment_v0.1.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Operational API (Vibe-Coder) — Scope
|
||||||
|
|
||||||
|
AP1.7 liefert Kern-Endpoints. **AP1.7b** ergänzt Parität:
|
||||||
|
|
||||||
|
| Fähigkeit | UI | Op-API heute | AP1.7b |
|
||||||
|
|-----------|-----|--------------|--------|
|
||||||
|
| Context / Next Action | ✓ | ✓ | — |
|
||||||
|
| Action Status | ✓ | ✓ | — |
|
||||||
|
| Evidence anlegen | ✓ | ✓ | — |
|
||||||
|
| Blocker melden | ✓ | ◐ | ✓ |
|
||||||
|
| Backlog → Action committen | ✓ | ✗ | ✓ |
|
||||||
|
| Recurring status | ✓ | ✗ | ✓ |
|
||||||
|
| work_cycle zuweisen | ✓ | ◐ | ✓ |
|
||||||
|
|
||||||
|
Auth: Actor Service Token (Tenant-scoped). Kein Gate-Verify, kein Lifecycle-Override über Op-API.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. AP2.1 Validation (nach Stufe-A-Flows)
|
||||||
|
|
||||||
|
**Nicht:** ein Dogfooding-Vorhaben auf Pi.
|
||||||
|
**Sondern:** PO füllt Report mit **echten, in der UI angelegten** Referenz-Vorhaben:
|
||||||
|
|
||||||
|
- A1 (Reifegrad)
|
||||||
|
- A2 (Linear)
|
||||||
|
- B2b (+ optional B3 Zeitbox)
|
||||||
|
- D1 wenn Stufe B bis dahin fertig
|
||||||
|
|
||||||
|
Vorlage: `docs/sprints/Sprint1_AP2_1_MVP_Validation_Report_v0.3.md` (neu bei AP2.1)
|
||||||
|
|
||||||
|
Go-Kriterium: MVP v0.3 §5 — pro Stufe-A-Archetyp Leitfrage ≤2 Min + Next Action begründet.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Dokumentenpriorität
|
||||||
|
|
||||||
|
Bei Konflikten:
|
||||||
|
|
||||||
|
1. `Kairo_MVP_Definition_v0.3.md`
|
||||||
|
2. **Dieses Dokument** (Execution Plan v0.2)
|
||||||
|
3. `ADP_Archetype_and_Method_Catalog_v0.2.md`
|
||||||
|
4. `Kairo_Corrected_MVP_Roadmap_v0.2.md` (AP-Historie)
|
||||||
|
5. `Kairo_Dogfooding_Mirror_Steering_v0.1.md` (optional, Dev-only)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. PO-Freigabe (offen)
|
||||||
|
|
||||||
|
- [ ] Execution Plan v0.2 als führende Priorisierung
|
||||||
|
- [ ] Dogfooding-Seed deprecated
|
||||||
|
- [ ] AP2.2a als nächstes Code-Paket
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Siehe auch: `Kairo_Implementation_Truth_Table_v0.1.md` § Referenz-Archetypen, `Kairo_Status_Review_and_Next_Steps_v0.2.md`*
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
# Jinkendo Kairo
|
# Jinkendo Kairo
|
||||||
## Status-Review & Nächste Schritte v0.1
|
## Status-Review & Nächste Schritte v0.1
|
||||||
|
|
||||||
|
> **Superseded ab 2026-07-12:** Siehe **`Kairo_Status_Review_and_Next_Steps_v0.2.md`** und **`Kairo_MVP_Execution_Plan_v0.2.md`**.
|
||||||
|
|
||||||
**Status:** PO-Review-Auswertung (living document)
|
**Status:** PO-Review-Auswertung (living document)
|
||||||
**Stand:** 2026-07-11
|
**Stand:** 2026-07-12
|
||||||
**Auslöser:** Vollständiger Plan/Ist/Soll-Abgleich, MVP-Review, Vorbereitung Dogfooding
|
**Auslöser:** Vollständiger Plan/Ist/Soll-Abgleich, MVP-Review, Dogfooding R2
|
||||||
**Bezug:** `Kairo_MVP_Definition_v0.3.md`, `Kairo_Implementation_Truth_Table_v0.1.md`, `Kairo_Corrected_MVP_Roadmap_v0.2.md`
|
**Bezug:** `Kairo_MVP_Definition_v0.3.md`, `Kairo_Implementation_Truth_Table_v0.1.md`, `Kairo_Corrected_MVP_Roadmap_v0.2.md`
|
||||||
**Dogfooding:** `Kairo_Dogfooding_Mirror_Steering_v0.1.md`
|
**Dogfooding:** `Kairo_Dogfooding_Mirror_Steering_v0.1.md`
|
||||||
|
|
||||||
|
|
@ -13,15 +15,15 @@
|
||||||
|
|
||||||
**Gesamtziel (unverändert):** Kairo ist der operative **Program Director** — Plan und Ist getrennt, Gates prüfbar, Steuerung archetyp- und methodengebunden, Agenten als Actors.
|
**Gesamtziel (unverändert):** Kairo ist der operative **Program Director** — Plan und Ist getrennt, Gates prüfbar, Steuerung archetyp- und methodengebunden, Agenten als Actors.
|
||||||
|
|
||||||
**Ist (2026-07-11, `develop` @ `b85a6ec`):**
|
**Ist (2026-07-12, `develop` @ `a097a82`):**
|
||||||
|
|
||||||
- **Foundation & OM:** tragfähig (~95 %)
|
- **Foundation & OM:** tragfähig (~95 %)
|
||||||
- **Plan/Gates/Infrastruktur:** weit (~70 %) — RoadmapItem, Checkliste, Graph Engine, Designer, Plan/Ist-Diff, Journey
|
- **Plan/Gates/Infrastruktur:** weit (~75 %) — RoadmapItem, Graph, Designer, Plan/Ist, Journey
|
||||||
- **IA / PM Work Modes:** Shell da (~60 %) — Polish offen
|
- **IA / PM Work Modes:** Shell da (~65 %) — AP1.9c ✓; Polish AP1.9b/d offen
|
||||||
- **Archetyp-Steuerung (MVP v0.3):** erster Slice AP2.0 (~40 %)
|
- **Archetyp-Steuerung (MVP v0.3):** Slice weit (~70 %) — AP2.0d ✓, AP1.7 ✓, AP2.0f ✓
|
||||||
- **MVP-Abnahfe Stufe A:** noch nicht validiert (~25 %)
|
- **MVP-Abnahfe Stufe A:** Validation vorbereitet (~40 %) — **AP2.1 nächstes PO-Gate**
|
||||||
|
|
||||||
**Urteil:** Technisch **weit über dem alten MVP-Slice** (`Initiative → Action`), produktlich **noch nicht MVP-nah** im Sinne von v0.3 — weil **Steuerung pro Archetyp**, **Cockpit-Signale** und **Referenz-Validierung** fehlen.
|
**Urteil:** Technisch **B2b-Infrastruktur steht** (Operational API, Execution-Graph, Zeitbox). Produktlich **MVP-nah** erst nach **AP2.1 Validation** auf Pi.
|
||||||
|
|
||||||
**Nächster strategischer Hebel:** Kairo-Jinkendo als **Referenz-Vorhaben B2b** in Kairo spiegeln (Dogfooding) — Plan bleibt in Git/Docs, Kairo trackt Ist + Fortschritt + Ergebnisse.
|
**Nächster strategischer Hebel:** Kairo-Jinkendo als **Referenz-Vorhaben B2b** in Kairo spiegeln (Dogfooding) — Plan bleibt in Git/Docs, Kairo trackt Ist + Fortschritt + Ergebnisse.
|
||||||
|
|
||||||
|
|
@ -38,16 +40,16 @@
|
||||||
| 3 | Ist committen | Actions, Tasks, Recurring | Actions ✓, Tasks ◐ AP1.5d, Recurring ✓ | Task-Roll-up ◐ |
|
| 3 | Ist committen | Actions, Tasks, Recurring | Actions ✓, Tasks ◐ AP1.5d, Recurring ✓ | Task-Roll-up ◐ |
|
||||||
| 4 | Kontrolle mit Begründung | Lifecycle, Methode, Next Action | AP2.0c Snapshot ◐ | Strategien unvollständig |
|
| 4 | Kontrolle mit Begründung | Lifecycle, Methode, Next Action | AP2.0c Snapshot ◐ | Strategien unvollständig |
|
||||||
| 5 | Journey nachvollziehbar | ≥5 Events | AP1.6a/b ◐ | nicht validiert |
|
| 5 | Journey nachvollziehbar | ≥5 Events | AP1.6a/b ◐ | nicht validiert |
|
||||||
| 6 | Leitfrage ≤2 Min | ohne CRUD-Wand | IA AP1.9a ✓, Inline-Forms ◐ | Polish AP1.9c/d |
|
| 6 | Leitfrage ≤2 Min | ohne CRUD-Wand | IA AP1.9a ✓, Kontrolle ◐ | Validation AP2.1 |
|
||||||
| 7 | Cockpit Portfolio-Attention | welches Vorhaben zuerst | AP1.8a Rang ✓, Signale ✗ | AP1.9c |
|
| 7 | Cockpit Portfolio-Attention | welches Vorhaben zuerst | AP1.8a ✓, AP1.9c ✓ | AP2.1 bestätigen |
|
||||||
|
|
||||||
**Score:** 0/7 voll ✓ · 7/7 ◐
|
**Score:** 2/7 voll ✓ · 5/7 ◐
|
||||||
|
|
||||||
### 2.2 Abnahfe-Stufen (Archetypen)
|
### 2.2 Abnahfe-Stufen (Archetypen)
|
||||||
|
|
||||||
| Stufe | Archetypen | Ist |
|
| Stufe | Archetypen | Ist |
|
||||||
|-------|------------|-----|
|
|-------|------------|-----|
|
||||||
| **A** | A1, A2, B2b, B3 minimal | **B2b am nächsten** (Kairo selbst); A1/A2 → AP2.0d; B3 → AP2.0f (`work_cycle` fehlt) |
|
| **A** | A1, A2, B2b, B3 minimal | **B2b bereit für Validation** — `work_cycle` ✓; AP2.1 PO-Gate |
|
||||||
| **B** | A3, B1, D1 | Katalog + Seeds, keine Strategien |
|
| **B** | A3, B1, D1 | Katalog + Seeds, keine Strategien |
|
||||||
| **C** | C1 | nur Spezifikation |
|
| **C** | C1 | nur Spezifikation |
|
||||||
|
|
||||||
|
|
@ -59,9 +61,9 @@ OM-Persistenz ██████░░ ~75%
|
||||||
Plan/Gates ██████░░ ~70%
|
Plan/Gates ██████░░ ~70%
|
||||||
IA / Modi █████░░░ ~60%
|
IA / Modi █████░░░ ~60%
|
||||||
Steering-Kern ████░░░░ ~50%
|
Steering-Kern ████░░░░ ~50%
|
||||||
Archetyp-Steuerung ███░░░░░ ~40%
|
Archetyp-Steuerung ██████░░ ~70%
|
||||||
MVP-Abnahfe A ██░░░░░░ ~25%
|
MVP-Abnahfe A ████░░░░ ~40%
|
||||||
Agent/MCP ░░░░░░░░ ~5%
|
Agent/MCP ██░░░░░░ ~15% (AP1.7 ✓; MCP deferred)
|
||||||
Dokumentation █████░░░ ~55% (nach diesem DOC-Slice)
|
Dokumentation █████░░░ ~55% (nach diesem DOC-Slice)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -85,8 +87,18 @@ Commits auf `develop` bis `b85a6ec` (Auszug):
|
||||||
| AP2.0a–c | Method-Stubs, Archetyp-Seeds, Kontrolle-Lagebild | MVP-B2b-Basis |
|
| AP2.0a–c | Method-Stubs, Archetyp-Seeds, Kontrolle-Lagebild | MVP-B2b-Basis |
|
||||||
| AP1.10c | Profil-Modal Archetyp/EFS | Anlage |
|
| AP1.10c | Profil-Modal Archetyp/EFS | Anlage |
|
||||||
|
|
||||||
**Frontend-Version:** `0.18.0-ap2.0`
|
**Frontend-Version:** `0.19.0-ap2.0f`
|
||||||
**Schema:** Migrationen 001–022
|
**Schema:** Migrationen 001–025
|
||||||
|
|
||||||
|
Zusätzlich seit 2026-07-11:
|
||||||
|
|
||||||
|
| Paket | Inhalt | Produktwert |
|
||||||
|
|-------|--------|-------------|
|
||||||
|
| AP1.9c | Cockpit-Signale auf Portfolio-Kacheln | Portfolio-Attention |
|
||||||
|
| AP1.16 | Execution-Graph, Plan-Outline-Kanten | Durchführungsplan |
|
||||||
|
| AP2.0d | Next-Action-Strategien pro Archetyp | Begründete Next Actions |
|
||||||
|
| AP1.7 | Operational Actor API + Service Tokens | Vibe-Coder ohne User-Login |
|
||||||
|
| AP2.0f | `work_cycle` / Sprint-Zeitbox (B3 minimal) | Agile Iteration auf Product |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -109,24 +121,18 @@ Priorität nach MVP v0.3 §9, Review 2026-07-11 und Dogfooding-Vorbereitung:
|
||||||
|
|
||||||
| Phase | Paket | Ziel | Abhängigkeit |
|
| Phase | Paket | Ziel | Abhängigkeit |
|
||||||
|-------|-------|------|--------------|
|
|-------|-------|------|--------------|
|
||||||
| **D0** | **DOC-Sync** | Truth Table, Gap Analysis, Roadmap §2–3, dieses Dokument | — |
|
| **D0** | **DOC-Sync** | Truth Table, Gap Analysis, Roadmap §2–3 | ✓ |
|
||||||
| **D1** | **Dogfooding R1** | Vorhaben „Kairo-Jinkendo“ in Kairo anlegen (Spiegel, manuell) | D0 |
|
| **D1** | **Dogfooding R1/R2** | Vorhaben + Ist-Spiegel (Seed) | ✓ |
|
||||||
| **1** | **AP1.9c** | Cockpit: Signale auf Portfolio-Kacheln | — |
|
| **1–3** | AP1.9c, AP1.16, AP2.0d | Cockpit, Graph, Strategien | ✓ Code |
|
||||||
| **2** | **AP1.9b/d** | Scope-Breadcrumb, Kontrolle-Polish | 1 optional parallel |
|
| **4** | AP1.7, AP2.0f | Operational API, Zeitbox | ✓ Code |
|
||||||
| **2b** | **AP1.16a–b** | Execution-Graph Schema + Engine (`ready_actions`) | **◐ Code** — Deploy |
|
| **5** | **AP2.1 / AP0.10d B2b** | **Validation auf Pi — PO-Gate** | 1–4 |
|
||||||
| **3** | **AP2.0d** | Next-Action-Strategien: maturity, sequential, recurring, queue | 2b |
|
| **6** | AP1.9b/d | Scope-Breadcrumb, Kontrolle-Polish | 5 optional |
|
||||||
| **4** | **Dogfooding R2** | Ist pflegen, Evidence mit Gitea-Links, Gate-Fortschritt | D1 |
|
| **7** | AP1.16c–d Rest | Planning Debt UI | parallel |
|
||||||
| **4b** | **AP1.16c–d** | Plan-Outline AP-Kanten, Planning Debt | 2b |
|
| **8** | Integration | Gitea-Webhook → Journey/Evidence | AP2.1 Go |
|
||||||
| **5** | **AP0.10d / AP2.1** | Validation B2b: Leitfrage-Test auf Pi | 3, 4 |
|
| **9** | MCP-Adapter | Cursor auf Operational API | 8 |
|
||||||
| **6** | **AP2.0f** | `work_cycle` / Sprint auf Product (B3 minimal) | 5 optional |
|
|
||||||
| **7** | **AP1.5d Rest** | Task-Detail, Roll-up-UI | parallel möglich |
|
|
||||||
| **8** | **AP1.7** | Operational Actor Interface | nach 5 |
|
|
||||||
| **9** | **Integration** | Gitea-Webhook → Journey/Evidence (Schicht 4) | AP1.7 |
|
|
||||||
| **10** | **MCP-Adapter** | Cursor-Agent auf Operational API | 8 |
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
D0 DOC ──► D1 Dogfooding anlegen ──► 1 AP1.9c ──► 2b AP1.16 ──► 3 AP2.0d ──► 4 Ist spiegeln
|
D0/D1 ✓ ──► AP1.9c/1.16/2.0d ✓ ──► AP1.7/2.0f ✓ ──► AP2.1 Validation (PO) ──► Integration/MCP
|
||||||
└──► 5 Validation ──► 8 AP1.7 ──► 10 MCP
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Bewusst deferred:** AP1.15d OR-Pfade, AP1.8b situativer Kontext, AP1.3 Hook Orchestrator (parallel möglich, nicht MVP-kritisch).
|
**Bewusst deferred:** AP1.15d OR-Pfade, AP1.8b situativer Kontext, AP1.3 Hook Orchestrator (parallel möglich, nicht MVP-kritisch).
|
||||||
|
|
@ -135,7 +141,7 @@ D0 DOC ──► D1 Dogfooding anlegen ──► 1 AP1.9c ──► 2b AP1.16
|
||||||
|
|
||||||
## 6. MVP-Urteil
|
## 6. MVP-Urteil
|
||||||
|
|
||||||
**Ist Kairo MVP-nah (v0.3)?** — **Nein**, aber **B2b-Abnahfe (Kairo steuert Kairo)** ist mit D1 + AP1.9c + AP2.0d + Validation in **2–3 Iterationen** erreichbar.
|
**Ist Kairo MVP-nah (v0.3)?** — **Bedingt** — B2b-Infrastruktur steht; **AP2.1 Validation** entscheidet Go für Stufe A.
|
||||||
|
|
||||||
Minimum für **Stufe-A-Abnahfe B2b**:
|
Minimum für **Stufe-A-Abnahfe B2b**:
|
||||||
|
|
||||||
|
|
|
||||||
53
docs/product/Kairo_Status_Review_and_Next_Steps_v0.2.md
Normal file
53
docs/product/Kairo_Status_Review_and_Next_Steps_v0.2.md
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
# Jinkendo Kairo
|
||||||
|
## Status-Review & Nächste Schritte v0.2
|
||||||
|
|
||||||
|
**Status:** PO-Kurskorrektur (living document)
|
||||||
|
**Stand:** 2026-07-12
|
||||||
|
**Ersetzt:** v0.1 §1/§5 (Dogfooding-first-Priorisierung)
|
||||||
|
**Führend:** `Kairo_MVP_Execution_Plan_v0.2.md`, `Kairo_MVP_Definition_v0.3.md` §5–9
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Executive Summary
|
||||||
|
|
||||||
|
**Gesamtziel:** Mehrere **Referenz-Archetypen** (A1, A2, B2b, …) sind **vollständig anleg- und pflegbar** — archetyp-gesteuert, ohne Todo-Explosion. Vibe-Coder pflegen Ist über **Operational API**.
|
||||||
|
|
||||||
|
**Ist (2026-07-12, `develop` + AP2.2a):**
|
||||||
|
|
||||||
|
- **Infrastruktur:** OM, Gates, Graph, IA-Shell, Execution-Graph, Strategien, work_cycle, Op-API — weit ✓
|
||||||
|
- **Produkt Stufe A:** ◐ — Starter-Kits (AP2.2a) beginnen; End-to-End-Flows pro Archetyp offen
|
||||||
|
- **Dogfooding-Seed:** deprecated — war nur Dev-Visualisierung
|
||||||
|
|
||||||
|
**Nächster Hebel:** **AP2.2a → AP2.2b–e** — Referenz-Vorhaben im **Produkt**, nicht in Seeds.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Roadmap — Nächste Schritte (korrigiert)
|
||||||
|
|
||||||
|
Siehe **`Kairo_MVP_Execution_Plan_v0.2.md` §4** für Details.
|
||||||
|
|
||||||
|
| Phase | Paket | Status |
|
||||||
|
|-------|-------|--------|
|
||||||
|
| 0 | Plan-Korrektur + Execution Plan v0.2 | ✓ |
|
||||||
|
| 1 | **AP2.2a** Starter-Kits / geführte Anlage | **→ Code** |
|
||||||
|
| 2 | AP1.9d Methoden-Default-UI | offen |
|
||||||
|
| 3 | AP2.2b–e A2, A1, B2b+B3 End-to-End | offen |
|
||||||
|
| 4 | AP1.7b Op-API Pflege-Parität | offen |
|
||||||
|
| 5 | AP2.1 Validation A1+A2+B2b (+D1) | nach Phase 3 |
|
||||||
|
| 6 | Stufe B (A3, B1, D1) + Schicht 4 | danach |
|
||||||
|
|
||||||
|
```text
|
||||||
|
Infrastruktur ✓ ──► AP2.2a Anlage ──► AP2.2b–e pro Archetyp ──► AP2.1 Validation
|
||||||
|
```
|
||||||
|
|
||||||
|
**Nicht prioritär:** seed_004, Dogfooding-R2-Sync, B2b-only-Validation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. MVP-Urteil
|
||||||
|
|
||||||
|
**MVP-nah?** — **Nein**, solange Referenz-Archetypen nicht **end-to-end im Produkt** nutzbar sind. Infrastruktur allein reicht nicht (MVP v0.3 §11 PO-Freigabe).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Vorgänger: `Kairo_Status_Review_and_Next_Steps_v0.1.md` (historisch bis 2026-07-11)*
|
||||||
|
|
@ -0,0 +1,152 @@
|
||||||
|
# AP2.2a — Archetyp-geführte Anlage & Starter-Kits
|
||||||
|
## Implementierungsauftrag v0.1
|
||||||
|
|
||||||
|
**Status:** freigegeben — **nächstes Code-Paket**
|
||||||
|
**Stand:** 2026-07-12
|
||||||
|
**PO-Basis:** `Kairo_MVP_Execution_Plan_v0.2.md` §5, `Kairo_MVP_Definition_v0.3.md` §5–7, `ADP_Archetype_and_Method_Catalog_v0.2.md` §3
|
||||||
|
**Vorgänger:** AP2.0b (Registry), AP1.10c (Profil-Modal), AP2.0c (Kontrolle)
|
||||||
|
**Nachfolger:** AP2.2b–e (End-to-End pro Archetyp), AP1.9d (Default-UI)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Ziel
|
||||||
|
|
||||||
|
Ein Nutzer legt ein **Referenz-Vorhaben** an — **ohne Seed, ohne CRUD-Wand** — und erhält:
|
||||||
|
|
||||||
|
1. **Archetyp** mit Default-Methode und verständlichem Label
|
||||||
|
2. Optional **Ausprägung** (`method_profile_key`: Kumite, Buch, Kairo-Dev)
|
||||||
|
3. **Starter-Kit**: minimale Plan-/Ist-Struktur passend zum Archetyp
|
||||||
|
4. **Guidance**: ein Satz Steuerungshinweis + Link zum nächsten sinnvollen Schritt
|
||||||
|
|
||||||
|
**Leitfrage-Test:** Nach Anlage in ≤3 Minuten in Kontrolle erkennbar: *Was ist der Typ dieses Vorhabens — und was ist als Nächstes dran?*
|
||||||
|
|
||||||
|
**Nicht-Ziel:** Voller Structure Builder, KI, Tenant-Designer.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Scope
|
||||||
|
|
||||||
|
### In Scope
|
||||||
|
|
||||||
|
| # | Lieferung |
|
||||||
|
|---|-----------|
|
||||||
|
| 1 | **Anlage-Flow** erweitern: Archetyp zuerst (Pflicht), Ausprägung wenn vorhanden, EFS-Kernfelder |
|
||||||
|
| 2 | **Starter-Kit-Service** (`backend/services/archetype_starter_kit.py`): idempotent nach `create_initiative` |
|
||||||
|
| 3 | Kits für **Stufe A**: A1, A2, B2b (+ optional B2a); B3-Hinweis auf `work_cycle` |
|
||||||
|
| 4 | **API** `GET /api/entity-archetypes/{key}/starter-preview` — was wird angelegt (read-only) |
|
||||||
|
| 5 | **UI**: Vorhaben anlegen — Vorschau „Das legen wir an“ + Guidance nach Create |
|
||||||
|
| 6 | pytest: pro Archetyp Kit-Struktur + Default-Methode |
|
||||||
|
|
||||||
|
### Out of Scope
|
||||||
|
|
||||||
|
- Dogfooding-Seed, Gitea-Webhook, MCP
|
||||||
|
- `chapter` item_type (→ AP2.2f)
|
||||||
|
- AP2.0e Recurring-Stufenwechsel (→ AP2.2c)
|
||||||
|
- Methoden-Default-Ansichten Ausführen-Modus (→ AP1.9d)
|
||||||
|
- Op-API Erweiterung (→ AP1.7b)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Starter-Kits (Spezifikation)
|
||||||
|
|
||||||
|
### A1 — `initiative.maturity_journey` / `maturity_progression`
|
||||||
|
|
||||||
|
| Element | Inhalt |
|
||||||
|
|---------|--------|
|
||||||
|
| RoadmapItems | 3× `maturity_stage` (planned → active → planned), sort_order 0,10,20 |
|
||||||
|
| Projects | 1× `project.maturity_journey` „Training“ |
|
||||||
|
| Recurring | 1× RecurringElement „Tägliche Übung“ (weekly, Platzhalter) |
|
||||||
|
| Guidance | „Aktuelle Stufe und heutige Übung steuern deinen nächsten Schritt.“ |
|
||||||
|
| Ausprägung | `maturity.karate_kumite` optional — mehr Stufen in Profil-JSON, Kit bleibt minimal |
|
||||||
|
|
||||||
|
### A2 — `initiative.linear_project` / `sequential_dependency`
|
||||||
|
|
||||||
|
| Element | Inhalt |
|
||||||
|
|---------|--------|
|
||||||
|
| RoadmapItems | 4× `milestone` als Gate-Kette (G1 active, G2–G4 planned), `requires`-Kanten |
|
||||||
|
| Projects | 2×: „Hauptpfad“, „Begleitung“ |
|
||||||
|
| Guidance | „Nächster Schritt am kritischen Pfad — Abhängigkeiten im Plan-Graph.“ |
|
||||||
|
|
||||||
|
### B2b — `initiative.product` / `continuous_product`
|
||||||
|
|
||||||
|
| Element | Inhalt |
|
||||||
|
|---------|--------|
|
||||||
|
| RoadmapItems | 2× `milestone` (Orientierung, nicht Micro-AP-Gates) |
|
||||||
|
| Projects | 2×: „Entwicklung“, „Betrieb“ |
|
||||||
|
| Backlog | 1× BacklogItem „Idee / Issue“ (open) |
|
||||||
|
| Guidance | „Eingang triagieren, dann committete Actions — optional Sprint-Zeitbox (B3).“ |
|
||||||
|
| Ausprägung | `product.kairo_dev` optional |
|
||||||
|
|
||||||
|
### B2a — `initiative.program` / `program_delivery` (minimal)
|
||||||
|
|
||||||
|
| Element | Inhalt |
|
||||||
|
|---------|--------|
|
||||||
|
| RoadmapItems | 3× `milestone` Phasen + Abschluss-Gate (planned/active) |
|
||||||
|
| Guidance | „Programm mit Abschluss — Gate-Horizont in Kontrolle.“ |
|
||||||
|
|
||||||
|
### B3 — Profil-Hinweis (kein eigener Archetyp)
|
||||||
|
|
||||||
|
- Kein separates Kit — bei B2b/B2a: leerer Hinweis „Sprint anlegen unter Plan → Zeitbox“
|
||||||
|
- Optional: 1× `work_cycle` planned „Iteration 1“ **nur wenn** Query-Param `include_work_cycle=true` bei Anlage
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Technische Umsetzung
|
||||||
|
|
||||||
|
### 4.1 Backend
|
||||||
|
|
||||||
|
```text
|
||||||
|
backend/services/archetype_starter_kit.py
|
||||||
|
get_starter_preview(archetype_key, method_profile_key?) -> StarterPreview
|
||||||
|
apply_starter_kit(tenant_id, initiative_id, archetype_key, ...) -> StarterResult
|
||||||
|
|
||||||
|
backend/routers/entity_archetypes.py (oder initiatives)
|
||||||
|
GET .../starter-preview?archetype_key=&method_profile_key=
|
||||||
|
|
||||||
|
services/initiatives.create_initiative(...)
|
||||||
|
optional: apply_starter_kit wenn apply_starter_kit=true (Default: true für Stufe A)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Regeln:**
|
||||||
|
|
||||||
|
- Idempotent: Re-Apply erzeugt keine Duplikate (Titel-Match wie Seeds)
|
||||||
|
- Tenant-scoped, Audit `initiative.starter_kit_applied`
|
||||||
|
- Keine hardcodierten Rechte — Capabilities wie bei `create_initiative`
|
||||||
|
|
||||||
|
### 4.2 Frontend
|
||||||
|
|
||||||
|
- `InitiativeForm` / Anlage-Modal: Archetyp-Auswahl prominent
|
||||||
|
- Vorschau-Panel aus `starter-preview`
|
||||||
|
- Nach Create: Toast + Link „Zur Kontrolle“ + Guidance-Text aus Snapshot
|
||||||
|
|
||||||
|
### 4.3 Tests
|
||||||
|
|
||||||
|
- `test_ap22a_starter_kit_a1.py` — Stufen + Recurring
|
||||||
|
- `test_ap22a_starter_kit_a2.py` — Gate-Kette + deps
|
||||||
|
- `test_ap22a_starter_kit_b2b.py` — Backlog + Projects
|
||||||
|
- `test_starter_preview_api.py`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. DoD
|
||||||
|
|
||||||
|
- [ ] Nutzer kann A1, A2, B2b Vorhaben **nur über UI** anlegen mit Starter-Struktur
|
||||||
|
- [ ] Default-Methode aus Archetyp — nicht `generic_operating` bei Stufe A
|
||||||
|
- [ ] Kontrolle zeigt nach Anlage sinnvolle Next Action (bestehende Strategien)
|
||||||
|
- [ ] Starter-Preview API dokumentiert in OpenAPI
|
||||||
|
- [ ] pytest grün
|
||||||
|
- [ ] Keine Abhängigkeit von `seed_004`
|
||||||
|
- [ ] Truth Table + Execution Plan: AP2.2a ✓
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Akzeptanz (manuell nach Deploy)
|
||||||
|
|
||||||
|
1. Neues Vorhaben „Test Küche“ (A2) → 4 Gates, 2 Projects, Kontrolle mit Next Action
|
||||||
|
2. Neues Vorhaben „Test Spagat“ (A1) → 3 Stufen, 1 Recurring
|
||||||
|
3. Neues Vorhaben „Test Product“ (B2b) → Backlog + Projects
|
||||||
|
4. ≤3 Min Leitfrage beantwortbar
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Siehe auch: `Kairo_MVP_Execution_Plan_v0.2.md`, `ADP_Archetype_and_Method_Catalog_v0.2.md` §3*
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "kairo-jinkendo-frontend",
|
"name": "kairo-jinkendo-frontend",
|
||||||
"version": "0.18.0-ap2.0",
|
"version": "0.20.0-ap2.2a",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
||||||
|
|
@ -4,3 +4,10 @@ export function listEntityArchetypes(entityType) {
|
||||||
const qs = entityType ? `?entity_type=${encodeURIComponent(entityType)}` : ''
|
const qs = entityType ? `?entity_type=${encodeURIComponent(entityType)}` : ''
|
||||||
return apiFetch(`/api/entity-archetypes${qs}`)
|
return apiFetch(`/api/entity-archetypes${qs}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getArchetypeStarterPreview(archetypeKey, methodProfileKey) {
|
||||||
|
const params = new URLSearchParams()
|
||||||
|
if (methodProfileKey) params.set('method_profile_key', methodProfileKey)
|
||||||
|
const qs = params.toString() ? `?${params}` : ''
|
||||||
|
return apiFetch(`/api/entity-archetypes/${encodeURIComponent(archetypeKey)}/starter-preview${qs}`)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'
|
||||||
import { INITIATIVE_STATUSES, PRIORITIES } from '../constants/status.js'
|
import { INITIATIVE_STATUSES, PRIORITIES } from '../constants/status.js'
|
||||||
import { INITIATIVE_STATUS_LABELS, PRIORITY_LABELS } from '../constants/status.js'
|
import { INITIATIVE_STATUS_LABELS, PRIORITY_LABELS } from '../constants/status.js'
|
||||||
import { INITIATIVE_ARCHETYPE_LABELS } from '../constants/initiativeArchetypes.js'
|
import { INITIATIVE_ARCHETYPE_LABELS } from '../constants/initiativeArchetypes.js'
|
||||||
import { listEntityArchetypes } from '../api/entityArchetypes.js'
|
import { listEntityArchetypes, getArchetypeStarterPreview } from '../api/entityArchetypes.js'
|
||||||
import {
|
import {
|
||||||
getInitiativeFields,
|
getInitiativeFields,
|
||||||
listArchetypeFieldDefinitions,
|
listArchetypeFieldDefinitions,
|
||||||
|
|
@ -23,6 +23,9 @@ export function InitiativeForm({
|
||||||
const [fieldDefinitions, setFieldDefinitions] = useState([])
|
const [fieldDefinitions, setFieldDefinitions] = useState([])
|
||||||
const [dynamicValues, setDynamicValues] = useState({})
|
const [dynamicValues, setDynamicValues] = useState({})
|
||||||
const [fieldsLoading, setFieldsLoading] = useState(false)
|
const [fieldsLoading, setFieldsLoading] = useState(false)
|
||||||
|
const [starterPreview, setStarterPreview] = useState(null)
|
||||||
|
const [starterLoading, setStarterLoading] = useState(false)
|
||||||
|
const isCreate = !initiativeId
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let cancelled = false
|
let cancelled = false
|
||||||
|
|
@ -81,6 +84,28 @@ export function InitiativeForm({
|
||||||
}
|
}
|
||||||
}, [initiativeId, archetypeKey])
|
}, [initiativeId, archetypeKey])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isCreate || !archetypeKey) {
|
||||||
|
setStarterPreview(null)
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
let cancelled = false
|
||||||
|
setStarterLoading(true)
|
||||||
|
getArchetypeStarterPreview(archetypeKey)
|
||||||
|
.then((preview) => {
|
||||||
|
if (!cancelled) setStarterPreview(preview)
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
if (!cancelled) setStarterPreview(null)
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
if (!cancelled) setStarterLoading(false)
|
||||||
|
})
|
||||||
|
return () => {
|
||||||
|
cancelled = true
|
||||||
|
}
|
||||||
|
}, [isCreate, archetypeKey])
|
||||||
|
|
||||||
async function handleSubmit(e) {
|
async function handleSubmit(e) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
const form = e.target
|
const form = e.target
|
||||||
|
|
@ -94,6 +119,7 @@ export function InitiativeForm({
|
||||||
priority: form.priority.value,
|
priority: form.priority.value,
|
||||||
owner_actor_id: form.owner_actor_id?.value || undefined,
|
owner_actor_id: form.owner_actor_id?.value || undefined,
|
||||||
dynamicFields: dynamicValues,
|
dynamicFields: dynamicValues,
|
||||||
|
apply_starter_kit: isCreate && starterPreview?.supported !== false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,6 +156,19 @@ export function InitiativeForm({
|
||||||
<span className="muted form-hint">{selectedArchetype.description}</span>
|
<span className="muted form-hint">{selectedArchetype.description}</span>
|
||||||
)}
|
)}
|
||||||
</label>
|
</label>
|
||||||
|
{isCreate && starterPreview?.supported && (
|
||||||
|
<div className="starter-kit-preview card-list-item compact">
|
||||||
|
<p className="muted form-hint">
|
||||||
|
<strong>Starter-Struktur:</strong>{' '}
|
||||||
|
{starterLoading
|
||||||
|
? ' wird geladen …'
|
||||||
|
: starterPreview.items.map((item) => item.title).join(' · ')}
|
||||||
|
</p>
|
||||||
|
{starterPreview.guidance && (
|
||||||
|
<p className="muted form-hint">{starterPreview.guidance}</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{actors.length > 0 && (
|
{actors.length > 0 && (
|
||||||
<label>
|
<label>
|
||||||
Verantwortlich (Owner)
|
Verantwortlich (Owner)
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ export function SteeringSnapshotPanel({
|
||||||
counts,
|
counts,
|
||||||
upcoming_milestones = [],
|
upcoming_milestones = [],
|
||||||
next_actions = [],
|
next_actions = [],
|
||||||
|
active_work_cycle = null,
|
||||||
} = snapshot
|
} = snapshot
|
||||||
const displayLabel =
|
const displayLabel =
|
||||||
lifecycle_label ||
|
lifecycle_label ||
|
||||||
|
|
@ -143,6 +144,19 @@ export function SteeringSnapshotPanel({
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{active_work_cycle && (
|
||||||
|
<p className="steering-work-cycle-row">
|
||||||
|
<span className="muted">Aktive Zeitbox: </span>
|
||||||
|
<strong>{active_work_cycle.title}</strong>
|
||||||
|
{active_work_cycle.goal_description && (
|
||||||
|
<span className="steering-method-description muted">
|
||||||
|
{' '}
|
||||||
|
— {active_work_cycle.goal_description}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
|
||||||
<ul className="steering-stat-pills" aria-label="Kurzüberblick">
|
<ul className="steering-stat-pills" aria-label="Kurzüberblick">
|
||||||
{statPills.map((pill) => (
|
{statPills.map((pill) => (
|
||||||
<li
|
<li
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user