Skip to content

feat(dystopia): record a karte as one booking-to-aftercare series with events - #1542

Merged
panicboat merged 15 commits into
refactor/dystopia-design-foundationfrom
feat/dystopia-karte-lifecycle
Oct 17, 2026
Merged

panicboat merged 15 commits into
refactor/dystopia-design-foundationfrom
feat/dystopia-karte-lifecycle

Conversation

@panicboat

@panicboat panicboat commented Oct 15, 2026 •

Copy link
Copy Markdown
Owner

Why

#1519 は、カルテを「星 + メモ」から「1 回の予約〜接客後 = 1 カルテ」に作り替え、段階ごとの出来事、記録中と完了の状態、キャスト単位の平均評価を持たせることを求めています。

4 段の stack の第 2 段です(第 1 段は #1521)。この段は proto・DB・use case・集計を作り替え、frontend の BFF・型・hook を合わせます。既存のカルテ画面は新しい形で動く最小限の改修にとどめ、新しい画面は第 3 段で作ります。

Decisions

  • 既存のカルテは破棄して表を作り直す(新しい形で必須の項目が既存データにないため)
  • 通報(ReportEntry と警告表示)を削除する(feat: カルテの体験を向上する #1519 で MVP 対象外)
  • 閲覧権の表(karte.access)と GetMyAccess を削除し、キャストかどうかで判定する(常に許可を返しており、使われていなかったため)
  • 記録中のカルテもホームの新着に載せる
  • 星は記録中なら未評価のままにでき、完了するときに必須。初期値は持たない
  • 平均評価はキャストの人格(プロフィール)単位で集計する。feat: カルテの体験を向上する #1519 §6.2 の「同一アカウントとして集計」は採らない。アカウント単位だと「N人が評価」と各カードの作成者・星から、人格同士が同一人物だと分かってしまい、複数プロフィールの「本人以外から同一人物と分からない」に反するため。代償として、同じ人が別の人格で書くと最大 5 人分の重みになる

Deploy impact

この PR の deploy では、新しい表(karte.kartes・karte.events)を作り、アプリから旧カルテの 3 表(karte.entries・karte.reports・karte.access)への参照を外します。旧表の削除は後の段の deploy で行います(dystopia/lambda/README.md の、破壊的なスキーマ変更は 2 回のデプロイに分ける規則に従う)。旧表を削除した時点で、本番の既存カルテとその行はすべて消えます。この PR の deploy 後は、既存カルテは画面に出なくなります。

Verification

  • monolith: HANAMI_ENV=test bundle exec rspec → 760 examples, 0 failures
  • frontend: pnpm exec vitest run → 156 files / 681 tests passed、pnpm exec tsc --noEmit エラーなし(pnpm exec next build はレビュー修正前の 2366754 で成功)
  • 実機(使い捨て DB + bin/grpc + next dev、puppeteer): レビュー修正前の 2366754 で 16/16 通過。集計単位の変更は rspec で確認(別アカウントのキャスト同士の下記の値は変わらない)
    • ゲストのプロフィールのカルテ欄が「未評価(完了したカルテはまだありません)」で、作成フォームの星は未選択
    • 予約・予約成立で作成 → 「記録中」「未評価」「予約・問い合わせ・予約成立」
    • 星なしでは「完了する」が押せず「完了するには星を選んでください」
    • 接客・途中終了は補足なしで追記できず、補足ありで最新の出来事になる
    • 星 4 で完了 → 「4.0 / 5.0」「1人が評価 · 1件の完了済みカルテ」
    • 別キャストが星 2 で完了 → 「3.0 / 5.0」「2人が評価 · 2件」、相手のカルテに作者操作は出ない
    • 最初のキャストが再オープン → 「2.0 / 5.0」「1人が評価 · 1件」
    • ホームのカルテタブに記録中のカルテが出る、作成メニュー → カルテで作成しトースト表示
    • ゲストにはナビにカルテが無く、/karte/my は「カルテはキャストだけが使えます」

Review fixes

最終レビューの指摘を受けて、次を直しました。

  • 平均評価をプロフィール単位にした(上記 Decisions)
  • 旧表を削除する migration をこの PR から外した(上記 Deploy impact)
  • 作成者の操作はカルテの行をロックしてから状態を確かめる(2 つのタブでの同時操作で、出来事 0 件のカルテや完了後の追記が起きないようにする)
  • 出来事の操作は、出来事の存在より先にキャストかどうかを判定する
  • 操作に失敗してもカードを取り直す
  • /karte/my はログイン状態の読み込みを待ち、ゲストのときは取得しない
  • 機能紹介から「有料機能」の表記を外した

Docs

  • spec: docs/superpowers/specs/2026-10-16-dystopia-karte-lifecycle-design.md
  • plan: docs/superpowers/plans/2026-10-16-dystopia-karte-lifecycle.md

Refs #1519

🤖 Generated with Claude Code

https://claude.ai/code/session_01DA9qTtJtm2tPquKk7hyPR5

@panicboat
panicboat added this pull request to stack #1543 October 15, 2026 16:54
@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2882ccd6-f0d1-4edc-9c43-ad938f9be443
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@panicboat panicboat changed the title docs(dystopia): specify a karte as one booking-to-aftercare record with events feat(dystopia): record a karte as one booking-to-aftercare series with events Oct 15, 2026
…th events

Issue #1519 turns a karte from a single rating with a note into the record
of one booking through aftercare, with events per stage, an open/closed
lifecycle and a reliability score averaged per cast. This spec covers the
backend and the frontend data layer; the new screens follow in stage 3.

Claude-Session: https://claude.ai/code/session_01DA9qTtJtm2tPquKk7hyPR5
Signed-off-by: panicboat <panicboat@gmail.com>
Every karte now counts toward the reliability score, and the cast who
records it always leaves a judgement. This departs from issue #1519,
which allowed an unrated karte.

Claude-Session: https://claude.ai/code/session_01DA9qTtJtm2tPquKk7hyPR5
Signed-off-by: panicboat <panicboat@gmail.com>
…s one

A preselected 3 would let an unconsidered score into the reliability average.

Claude-Session: https://claude.ai/code/session_01DA9qTtJtm2tPquKk7hyPR5
Signed-off-by: panicboat <panicboat@gmail.com>
…o close it

A karte started at the reservation stage has nothing to judge yet, so the
rating may wait until the cast closes the record; every closed karte still
carries one and counts toward the reliability score.

Claude-Session: https://claude.ai/code/session_01DA9qTtJtm2tPquKk7hyPR5
Signed-off-by: panicboat <panicboat@gmail.com>
…est per cast

Signed-off-by: panicboat <panicboat@gmail.com>
…se and reopen

Signed-off-by: panicboat <panicboat@gmail.com>
… reports and access

Signed-off-by: panicboat <panicboat@gmail.com>
…an access flag

Signed-off-by: panicboat <panicboat@gmail.com>
…utes and hooks

Signed-off-by: panicboat <panicboat@gmail.com>
…m the existing screens

Signed-off-by: panicboat <panicboat@gmail.com>
… karte row on author writes and keep the old tables for a later deploy

Reliability groups by the author profile so two profiles of one account cannot be linked from the rater count.
Author operations lock the karte row before checking its state, event deletion authorizes the cast before looking the event up, and the destructive drop of the old tables moves to a later deploy.

Claude-Session: https://claude.ai/code/session_01DA9qTtJtm2tPquKk7hyPR5
Signed-off-by: panicboat <panicboat@gmail.com>
…for auth before /karte/my and drop the paid label from the tour

Claude-Session: https://claude.ai/code/session_01DA9qTtJtm2tPquKk7hyPR5
Signed-off-by: panicboat <panicboat@gmail.com>
…g the old karte tables

Claude-Session: https://claude.ai/code/session_01DA9qTtJtm2tPquKk7hyPR5
Signed-off-by: panicboat <panicboat@gmail.com>
@panicboat
panicboat force-pushed the feat/dystopia-karte-lifecycle branch from 0c4347c to c642d26 Compare October 16, 2026 09:04
@panicboat-github-workflow-bot panicboat-github-workflow-bot Bot added deploy:frontend Auto-generated deployment label deploy:monolith Auto-generated deployment label and removed deploy:frontend Auto-generated deployment label labels Oct 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Kustomize Diff

Service: monolith
Environment: production

No changes

@github-actions

Copy link
Copy Markdown
Contributor

Kustomize Diff

Service: frontend
Environment: production

No changes

@panicboat
panicboat marked this pull request as ready for review October 17, 2026 01:44
@panicboat
panicboat merged commit 72f419c into main Oct 17, 2026
27 of 31 checks passed
@panicboat
panicboat deleted the feat/dystopia-karte-lifecycle branch October 17, 2026 01:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deploy:frontend Auto-generated deployment label deploy:monolith Auto-generated deployment label

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant