feat(B09 설계내역서): 불러오기 끝 = 지난번 이음 바로 잇고 남은 제안만 창에(남은 0 = 창 없음) · 잊은 짝 곁 느슨한 기억 안 좁힘 (PLAN 707-4 덧)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-31 17:46:00 +09:00
co-authored by Claude Sonnet 5.5
parent 0959f28717
commit 74f3fb8009
4 changed files with 32 additions and 10 deletions
+4 -7
View File
@@ -98,16 +98,13 @@ def _loose(key: str) -> str:
def recall(memory: dict[str, dict[str, Any]], row: dict[str, Any]) -> dict[str, Any] | None:
"""기억 한 칸 — 같은 열쇠 · 없으면 품명 · 단위 같고 짝이 하나인 것(잊은 칸 = 없음)."""
"""기억 한 칸 — 같은 열쇠 · 없으면 품명 · 단위 같고 짝이 하나인 것 ·
잊은 칸은 없음 취급 + 느슨한 기억에서는 다른 짝으로 셈(잊은 짝 곁에서 하나로 좁히지 않음)."""
key = key_of(row)
if isinstance(memory.get(key), dict):
return None if memory[key].get(FORGOT) else memory[key]
loose = [
v
for k, v in memory.items()
if isinstance(v, dict) and not v.get(FORGOT) and _loose(k) == _loose(key)
]
return loose[0] if len({v.get("확정") for v in loose}) == 1 else None
loose = [v for k, v in memory.items() if isinstance(v, dict) and _loose(k) == _loose(key)]
return loose[0] if len({v.get("확정") for v in loose}) == 1 and loose[0].get("확정") else None
def _targets(rows: list[dict[str, Any]]) -> dict[str, dict[str, Any]]:
+1 -1
View File
@@ -161,7 +161,7 @@ export function createBillImport(
// 창 닫고 다시 그림 — 표 높이(fillViewport)가 열린 창 가림막을 아래 자리로 셈
close();
done(got.payload, made);
void openBillLink(user(), done, mode.value); // 707-4 다음: 우리 공종으로 잇기
void openBillLink(user(), done, mode.value, true); // 707-4 다음: 지난번 이음 바로 · 남은 것만 창
const n = got.알림 || {};
const head = `새 줄 ${n.실음} · 붙임 ${n.붙임} · 지움 ${n.지움} · 이음 ${n.이음}${tail} — [저장]해야 남음`;
const off: Row[] = got.어긋남 || [];
+25 -2
View File
@@ -110,16 +110,39 @@ function pickOurs(spots: Row[], line: Row, take: (key: string) => void): void {
});
}
/** 잇기 창 — user = 지금 캐시 · mode = 불러올 때 고른 갈래(없으면 마지막) */
export async function openBillLink(user: Row, done: LinkDone, mode?: string): Promise<void> {
/** 잇기 창 — user = 지금 캐시 · mode = 불러올 때 고른 갈래(없으면 마지막) ·
* fresh = 불러오기 끝에서 부름 — 지난번 이음은 먼저 바로 잇고 남은 것만 창에(남은 0 = 창 없음) */
export async function openBillLink(
user: Row,
done: LinkDone,
mode?: string,
fresh = false,
): Promise<void> {
if (mode === "take" || mode === "price") lastMode = mode;
let cur = user;
let seen: Row;
try {
seen = await post("suggest", { user: cur });
if (fresh && seen.저절로) {
const got = await post("apply", {
pairs: [],
auto: true,
mode: lastMode,
counts: {},
user: cur,
});
done(got.payload, got.user);
cur = got.user;
showToast(
`지난번 이음 ${got.알림.이음 + got.알림.묶음} 줄 바로 이음 — [저장]해야 남음`,
"success",
);
seen = await post("suggest", { user: cur });
}
} catch (error) {
return fail("제안을 못 받음")(error);
}
if (fresh && !seen.남은.length) return; // 남은 줄 없음 — 창 안 뜸
if (!seen.남은.length && !seen.이은.length) return; // 불러온 줄 없음
let busy = false;
const run = (job: () => Promise<Row | void>): void => {
+2
View File
@@ -297,5 +297,7 @@ def test_잊은_짝_느슨한_기억에도_안_나옴(tmp_path, monkeypatch):
memory = route.recalled(user)
assert lk.recall(memory, row) is None # 잊음 = 느슨한 기억도 끊김
assert lk.recall(memory, other) == live # 다른 줄은 그대로
third = {"name": "토사절취", "spec": "C", "unit": "m3"}
assert lk.recall(memory, third) is None # 잊은 짝 곁에서는 느슨하게 안 좁힘
route.keep(user, {lk.key_of(row): live}) # 다시 이음 = 풀림
assert lk.recall(route.recalled(user), row) == live