전 저장소 리팩터링과 SSOT 정비
This commit is contained in:
parent
14ecbd4e7d
commit
3dfddcac6f
173 changed files with 19679 additions and 6952 deletions
|
|
@ -117,7 +117,9 @@ def load_file_personas(persona_dir: Path = REPO_PERSONA_DIR) -> list[PersonaCard
|
|||
|
||||
def built_in_personas() -> list[PersonaCard]:
|
||||
"""Return deterministic built-in catalog cards from code seeds plus repo JSON cards."""
|
||||
cards: dict[str, PersonaCard] = {card.code.upper(): card for card in SEED_PERSONAS.values()}
|
||||
cards: dict[str, PersonaCard] = {
|
||||
card.code.upper(): card for card in SEED_PERSONAS.values()
|
||||
}
|
||||
for card in load_file_personas():
|
||||
cards.setdefault(card.code.upper(), card)
|
||||
return [cards[code] for code in sorted(cards)]
|
||||
|
|
@ -222,7 +224,14 @@ def seed_fallback_persona(code: str) -> CatalogPersona | None:
|
|||
normalized = code.strip().upper()
|
||||
card = get_seed_persona(normalized)
|
||||
if card is None:
|
||||
card = next((entry for entry in load_file_personas() if entry.code.upper() == normalized), None)
|
||||
card = next(
|
||||
(
|
||||
entry
|
||||
for entry in load_file_personas()
|
||||
if entry.code.upper() == normalized
|
||||
),
|
||||
None,
|
||||
)
|
||||
if card is None:
|
||||
return None
|
||||
return CatalogPersona(
|
||||
|
|
@ -448,6 +457,83 @@ async def get_persona_draft_record(
|
|||
return persona_draft_record_from_row(row) if row is not None else None
|
||||
|
||||
|
||||
async def _insert_persona_card(
|
||||
conn: Any,
|
||||
*,
|
||||
persona_id: str,
|
||||
card: PersonaCard,
|
||||
version: int,
|
||||
next_status: str,
|
||||
author_id: str,
|
||||
returning_columns: str,
|
||||
) -> Any:
|
||||
"""Insert one immutable persona version from the canonical PersonaCard shape."""
|
||||
|
||||
return await conn.fetchrow(
|
||||
f"""
|
||||
INSERT INTO app.persona_card (
|
||||
persona_id, code, version, status, display_name, difficulty,
|
||||
theory_target, demographics, presenting, history, big5,
|
||||
resistance, speech_style, affect_baseline, ccd,
|
||||
dsm5_dimensional, source_provenance, is_synthetic, triggers,
|
||||
created_by
|
||||
)
|
||||
VALUES (
|
||||
$1::uuid, $2, $3, $4, $5, $6,
|
||||
$7::text[], $8::jsonb, $9::jsonb, $10::jsonb, $11::jsonb,
|
||||
$12::jsonb, $13::jsonb, $14::jsonb, $15::jsonb,
|
||||
$16::jsonb, $17, $18, $19::jsonb, $20::uuid
|
||||
)
|
||||
RETURNING {returning_columns}
|
||||
""",
|
||||
persona_id,
|
||||
card.code,
|
||||
version,
|
||||
next_status,
|
||||
card.display_name,
|
||||
card.difficulty,
|
||||
card.theory_target,
|
||||
card.demographics,
|
||||
card.presenting,
|
||||
card.history,
|
||||
card.big5,
|
||||
card.resistance,
|
||||
card.speech_style,
|
||||
card.affect_baseline,
|
||||
card.ccd,
|
||||
card.dsm5_dimensional,
|
||||
card.source_provenance,
|
||||
card.is_synthetic,
|
||||
card.triggers,
|
||||
author_id,
|
||||
)
|
||||
|
||||
|
||||
async def _record_persona_create_audit(
|
||||
conn: Any,
|
||||
*,
|
||||
author_id: str,
|
||||
action: str,
|
||||
persona_id: str,
|
||||
next_status: str,
|
||||
card: PersonaCard,
|
||||
version: int,
|
||||
) -> None:
|
||||
await conn.execute(
|
||||
"""
|
||||
INSERT INTO audit.audit_log (
|
||||
actor_uid, action, target_kind, target_id, detail
|
||||
)
|
||||
VALUES ($1::uuid, $2, $3, $4, $5::jsonb)
|
||||
""",
|
||||
author_id,
|
||||
action,
|
||||
"persona_card",
|
||||
persona_id,
|
||||
{"next_status": next_status, "code": card.code, "version": version},
|
||||
)
|
||||
|
||||
|
||||
async def create_persona_draft(
|
||||
*,
|
||||
card: PersonaCard,
|
||||
|
|
@ -470,60 +556,23 @@ async def create_persona_draft(
|
|||
""",
|
||||
card.code,
|
||||
)
|
||||
row = await conn.fetchrow(
|
||||
f"""
|
||||
INSERT INTO app.persona_card (
|
||||
persona_id, code, version, status, display_name, difficulty,
|
||||
theory_target, demographics, presenting, history, big5,
|
||||
resistance, speech_style, affect_baseline, ccd,
|
||||
dsm5_dimensional, source_provenance, is_synthetic, triggers,
|
||||
created_by
|
||||
)
|
||||
VALUES (
|
||||
$1::uuid, $2, $3, $4, $5, $6,
|
||||
$7::text[], $8::jsonb, $9::jsonb, $10::jsonb, $11::jsonb,
|
||||
$12::jsonb, $13::jsonb, $14::jsonb, $15::jsonb,
|
||||
$16::jsonb, $17, $18, $19::jsonb, $20::uuid
|
||||
)
|
||||
RETURNING {_REVIEW_COLUMNS}
|
||||
""",
|
||||
persona_id,
|
||||
card.code,
|
||||
int(version or 1),
|
||||
next_status,
|
||||
card.display_name,
|
||||
card.difficulty,
|
||||
card.theory_target,
|
||||
card.demographics,
|
||||
card.presenting,
|
||||
card.history,
|
||||
card.big5,
|
||||
card.resistance,
|
||||
card.speech_style,
|
||||
card.affect_baseline,
|
||||
card.ccd,
|
||||
card.dsm5_dimensional,
|
||||
card.source_provenance,
|
||||
card.is_synthetic,
|
||||
card.triggers,
|
||||
author_id,
|
||||
row = await _insert_persona_card(
|
||||
conn,
|
||||
persona_id=persona_id,
|
||||
card=card,
|
||||
version=int(version or 1),
|
||||
next_status=next_status,
|
||||
author_id=author_id,
|
||||
returning_columns=_REVIEW_COLUMNS,
|
||||
)
|
||||
await conn.execute(
|
||||
"""
|
||||
INSERT INTO audit.audit_log (
|
||||
actor_uid, action, target_kind, target_id, detail
|
||||
)
|
||||
VALUES ($1::uuid, $2, $3, $4, $5::jsonb)
|
||||
""",
|
||||
author_id,
|
||||
"persona_draft_create",
|
||||
"persona_card",
|
||||
persona_id,
|
||||
{
|
||||
"next_status": next_status,
|
||||
"code": card.code,
|
||||
"version": int(row["version"]),
|
||||
},
|
||||
await _record_persona_create_audit(
|
||||
conn,
|
||||
author_id=author_id,
|
||||
action="persona_draft_create",
|
||||
persona_id=persona_id,
|
||||
next_status=next_status,
|
||||
card=card,
|
||||
version=int(row["version"]),
|
||||
)
|
||||
return persona_review_item_from_row(row)
|
||||
|
||||
|
|
@ -577,60 +626,23 @@ async def create_persona_revision_from_existing(
|
|||
""",
|
||||
card.code,
|
||||
)
|
||||
row = await conn.fetchrow(
|
||||
f"""
|
||||
INSERT INTO app.persona_card (
|
||||
persona_id, code, version, status, display_name, difficulty,
|
||||
theory_target, demographics, presenting, history, big5,
|
||||
resistance, speech_style, affect_baseline, ccd,
|
||||
dsm5_dimensional, source_provenance, is_synthetic, triggers,
|
||||
created_by
|
||||
)
|
||||
VALUES (
|
||||
$1::uuid, $2, $3, $4, $5, $6,
|
||||
$7::text[], $8::jsonb, $9::jsonb, $10::jsonb, $11::jsonb,
|
||||
$12::jsonb, $13::jsonb, $14::jsonb, $15::jsonb,
|
||||
$16::jsonb, $17, $18, $19::jsonb, $20::uuid
|
||||
)
|
||||
RETURNING {_CARD_COLUMNS}, created_at, approved_at
|
||||
""",
|
||||
persona_id,
|
||||
card.code,
|
||||
int(version or 1),
|
||||
next_status,
|
||||
card.display_name,
|
||||
card.difficulty,
|
||||
card.theory_target,
|
||||
card.demographics,
|
||||
card.presenting,
|
||||
card.history,
|
||||
card.big5,
|
||||
card.resistance,
|
||||
card.speech_style,
|
||||
card.affect_baseline,
|
||||
card.ccd,
|
||||
card.dsm5_dimensional,
|
||||
card.source_provenance,
|
||||
card.is_synthetic,
|
||||
card.triggers,
|
||||
author_id,
|
||||
row = await _insert_persona_card(
|
||||
conn,
|
||||
persona_id=persona_id,
|
||||
card=card,
|
||||
version=int(version or 1),
|
||||
next_status=next_status,
|
||||
author_id=author_id,
|
||||
returning_columns=f"{_CARD_COLUMNS}, created_at, approved_at",
|
||||
)
|
||||
await conn.execute(
|
||||
"""
|
||||
INSERT INTO audit.audit_log (
|
||||
actor_uid, action, target_kind, target_id, detail
|
||||
)
|
||||
VALUES ($1::uuid, $2, $3, $4, $5::jsonb)
|
||||
""",
|
||||
author_id,
|
||||
"persona_revision_create",
|
||||
"persona_card",
|
||||
persona_id,
|
||||
{
|
||||
"next_status": next_status,
|
||||
"code": card.code,
|
||||
"version": int(row["version"]),
|
||||
},
|
||||
await _record_persona_create_audit(
|
||||
conn,
|
||||
author_id=author_id,
|
||||
action="persona_revision_create",
|
||||
persona_id=persona_id,
|
||||
next_status=next_status,
|
||||
card=card,
|
||||
version=int(row["version"]),
|
||||
)
|
||||
return persona_draft_record_from_row(row)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue