Skip to content

List 53 — The manual test script for the readiness build (0.12.0) ​

Status: Active · Last reviewed: 2026-11-14 · Owner: the owner's hands, on one phone with a second phone beside it. Before: pre-build and post-build checklists. Older lists (1 to 52) in device-checklists.md were written for the 0.11.0 build and are not a guide to this one.

Read this first ​

Everything in this list is a first-ever check on a device. Nothing built since the update pause (2026-10-14) has run on a phone, in a phone browser or in KakaoTalk's browser. The pages were rebuilt and tested by machines that cannot see a screen, a keyboard, a finger or a real network. So expect surprises, and write down what you see, not what you expect to see.

Twenty items are marked ★. They are the riskiest: either they use something that exists only in the new build (a new native part, a new server rule), or they involve two people at once, or they changed the money or privacy rules. If you run out of time, do the ★ items first, in the order printed.

How to mark. Pass, Fail or Skipped, with one line for a Fail. If a step differs from "Expect", do not retry five times; take a screenshot and go on to the next item. Where an item says "label to confirm", the machine could not give the exact word on the screen; describe what you see.

How the items read. Each item says who signs in on which phone, what data it uses, the steps, what you should see (Expect), and, where it settles a recorded open item, the release-evidence number (Settles, for example S22 in release evidence). Korean words in quotes or code are copied from the app's text; tap exactly those.

You do not type any command in this list. After each group, tell the lead the group is done; the lead reads the server's and the phones' error reports.

Accounts and data ​

Phone A signs in as the developer account (e-mail and password typed; the password is in your two untracked env files). It owns "QA 운영 클럽", hosts the fee'd 매치 and is an admin of the opposing club. Phone B signs in as a seeded person; their e-mail is qaready{n}@test.twomore.dev and the password is the seed password you set as a function secret (see credentials). Sign out of one and in as another on the same phone when you only have one phone: the item says which person.

Person (e-mail number)Name in the appState they holdUsed in
qaready1QA 상대 클럽장owner of the opposing clubC11
qaready3QA 가입 제안 기다림a waiting membership offer from QA 운영 클럽C1
qaready4, 5, 6QA 가입 제안 수락 / 거절 / 취소an offer already accepted, declined, cancelledC2 (look only)
qaready7QA 가입 후보a guest on the shortlist, no offer yetC2, C3
qaready8QA 가입 후보 추천됨a candidate proposed, no offer yetC2
qaready9QA 사유 요청 기다림an excusal request waiting for an officialF4
qaready10QA 사유 인정 직후excused a moment ago; the ten-minute undo is openF4
qaready11, 12QA 사유 거절됨 / 인정됨answered an hour ago; the undo is overF4 (look only)
qaready13QA 자리 보유 입금 전holds a seat on the fee'd 매치, not paidE1
qaready14QA 입금 확인됨paid, host confirmedE2, E4
qaready15QA 환불 기다림cancelled; the refund waits on the hostE3
qaready16QA 환불 받음cancelled; refund already receivedE3 (look only)
qaready17 to 20QA 선수 하나 to 넷players of the finished 매치 with scoresF1, F2
qaready21QA 내가 차단한 사람the developer account blocked this personH5
qaready22QA 나를 차단한 사람this person blocked the developer accountH5
qaready23QA 활동 비공개chose "private" for club and attendanceH1
qaready24QA 활동 공개chose "public" for club and attendanceH1
qawithdraw1QA 탈퇴 연습a throwaway account with one future seatH6

Places and things: club "QA 운영 클럽" (the main one; members include the players and the askers); the fee'd 매치 "QA 매치 참가비 15,000" in club "QA 매치 모임" (15,000 won; the bank is a made-up 국민은행 account); club "QA 회비 클럽" (a one-off dues plan "QA 코트 대관 회비" and an opening ledger balance); the finished 매치 "QA 결석 사유 확인 매치"; the opposing clubs "QA 대항전 상대 클럽" (a proposal waits for you to answer) and "QA 지난 대항전 상대 클럽" (a settled challenge); club "QA 공개 프로필 클럽" (one you are not in); the throwaway 매치 "QA 탈퇴 연습 매치"; the developer account has already hidden one news row, muted one club's news, blocked qaready21 and been blocked by qaready22.

The table above is confirmed against the seed lane's report and its local run: readiness_qa seeded the small world and the 22 state checks passed on 2026-11-14 (yarn qa:seed --local --chains readiness_qa, local stack only; hosted is not seeded). The already-corrected score that F1 expects exists on the small world (readiness_qa) only: on readiness_full (the largest world) the correction state and the world reconcile are not built, so F1 step 1 shows no corrected second match there. If a person or club is missing on the phone, the seed has not run on that project: say so and skip the item.

Items that need the hosted world seeded with readiness_qa are marked needs seed. Items that need no seed use whatever is on the project.


A. Entry and shell ​

A1 ★ Sign in. Phone A, signed out.

  1. Open the app. Tap the "Dev" button under the two fields (preview builds carry it since 2026-11-15, on the owner's instruction). To test typing instead: tap the e-mail field and type the developer e-mail, tap the password field and type the password, tap 로그인.
  2. Expect: 홈 appears with content. No raw error text anywhere.
  3. Type a wrong password once first (before the right one). Expect a line like "이메일 로그인에 실패했어요" (or the app's sign-in failure line), and the fields still filled in. Settles: S29 (the typed sign-in), S11 (first device run).

A2 ★ Start screen in light and dark. Phone A.

  1. Close the app fully. Set the phone to the light appearance and open the app. Expect a white start screen and no flash of another colour before the first page.
  2. Close it, set the phone to dark, open again. Expect a dark start screen of the same near-black as the app.
  3. Leave the app and look at its icon on the phone's home screen and in the app drawer (Android: try the round, the squircle and the square shape in the launcher's settings). Expect the mark on a near-black ground (the softer ink, #15181A), whole in every shape and not cropped, not on white. Settles: S11 (new splash with a dark variant; never seen on a device).

A3 Still signed in. Phone A. Close the app fully and open it. Expect 홈 with content, not the sign-in page.

A4 The five tabs and the tab press. Phone A.

  1. Tap 홈, 클럽, 경기, 기록, 프로필 in turn. Expect each opens with content, no raw error text.
  2. On each tab, scroll down, open one item, then tap that same tab in the bar. Expect: the page goes back to the tab's first page, and a second tap scrolls to the top. Settles: S11.

A5 ★ 화면 모드 reaches the phone. Phone A, with the phone itself set to LIGHT.

  1. 프로필, 설정, 화면 모드: choose 다크. Expect the app turns dark and the phone's status-bar icons turn light. Tap a text field: the keyboard should be dark. Open a date or time picker (for example 일정 만들기): it should be dark.
  2. Choose 라이트 after setting the phone to dark: the reverse. Choose 시스템: the app follows the phone again (change the phone setting to check). Settles: S11 (RD-8; the app's choice reaching the system bars, keyboard and pickers is device-only).

A6 Dark and large text. Phone A. Set the phone's text size to the largest, and use dark. Open 홈, 클럽, 경기, 기록, 프로필. Expect: every number and button is readable, names wrap onto a second line rather than being cut, no row collapses into a single line or overlaps. Settles: S11 (the rendered check is a machine's look; this is yours).

A6b Dark fills can be told from the page (batch 66). Phone A in dark. (1) Open a form with an unfinished main button (for example 일정 만들기 before the required fields): the pale soft button is a clear shape against the page. (2) A person with no photo: the letter avatar is a clear disc. (3) A grey notice (for example the offline strip or a Notice on a session): its box is visible against the page. (4) Open any dialog (for example 로그아웃): its panel has a thin edge against the dimmed page. Expect each of the four to read as a shape without effort; the text on them stays easy to read. Settles: S51 (a) dark fills (no picture of a real screen has been taken).

A7 ★ Cold start with no network. Phone A. Turn on airplane mode, close the app fully, open it. Expect: the offline page (the app says "오프라인이에요" and "연결되면 자동으로 다시 불러와요"), not a blank page and not yesterday's data; the app starts and does not crash. (Old List 47 row 3 expected cached lists; that is no longer true: the stored copy is deleted at every start.) Turn airplane mode off: the page loads by itself. Settles: S30.

A8 After one hour in the background. Phone A. Leave the app in the background for an hour, then open it. Expect the page you were on shows its data (not an empty list) within a few seconds.


B. 홈 ​

B1 홈 content. Phone A. Expect the next game, a "할 일" lane with tasks (for example 입금 확인), and the news rows. Tap the next game: it opens that 일정.

B2 Hide and mute news. Phone A, needs seed for the first clause.

  1. On a news row choose 숨기기. Expect the toast "소식을 숨겼어요" and the row goes.
  2. On another choose 이 클럽 소식 끄기. Expect "이 클럽 소식을 껐어요" and that club's rows go. Come back later: they stay hidden.

B3 The 홈 button. Phone A. Tap the round add button on 홈. Expect the question "어느 클럽의 일정인가요?" with your clubs and "클럽 없이 매치로". Close it without choosing.


C. 클럽 ​

C1 ★ A membership offer, on two phones. Phone B signs in as qaready3 ("QA 가입 제안 기다림"); phone A is the developer account. needs seed.

  1. Phone A: 클럽, "QA 운영 클럽", 관리, 멤버 관리. Expect a row for qaready3 marked "답을 기다리고 있어요" with a quiet "제안 취소" and no approve button.
  2. Phone B: 클럽 tab. Expect "QA 운영 클럽" is the FIRST row in 내 클럽, with the tag "가입 제안이 와 있어요", and no button on the row. Tap it.
  3. Phone B on the club page: expect the line "이 클럽의 운영진이 가입을 제안했어요" and two buttons, 수락 (the main one) and a quiet 거절.
  4. Tap 수락. Expect the button shows it is working, then the club page opens as a member's.
  5. Phone A: the offer row is gone from the waiting list and the person is a member; a "member joined" notice may arrive. Settles: S36, S42 (offer pages never run on a device).

C2 ★ Send an offer, then decline it. Phone A as the developer account; phone B as qaready7 ("QA 가입 후보"). needs seed.

  1. Phone A: 멤버 관리, the guest list. On qaready7 tap "후보 추가" (toast "가입 후보에 추가했어요"); the person moves under "가입 후보". Tap "가입 제안 보내기". Expect the toast "가입 제안을 보냈어요".
  2. Phone B: open 클럽: the offer is the first row with "가입 제안이 와 있어요". Open the club. Tap 거절.
  3. Expect a dialog "QA 운영 클럽의 가입 제안을 거절할까요?" (the club's name in it) with "거절해도 운영진이 나중에 다시 제안할 수 있어요". Confirm. Expect the toast "가입 제안을 거절했어요" and the page returns to the ordinary join band.
  4. Phone A: the person is an ordinary guest again, and a decline notice arrived. Settles: S36.

C3 Cancel an offer. Phone A sends an offer to qaready8, phone B (qaready8) opens the club page and leaves it open. Phone A taps "제안 취소": dialog "…님께 보낸 가입 제안을 취소할까요?" with "취소해도 다시 보낼 수 있어요"; confirm; toast "가입 제안을 취소했어요". Phone B: press 수락 (or reload): expect the line "이미 끝난 제안이에요" and the ordinary join band, never a joined club. Limit (optional): send and cancel the same person's offer until the fourth try in a week: expect "같은 분께는 일주일에 세 번까지 제안할 수 있어요" in a dialog, not a toast.

C4 ★ Create a club and its first session. Phone A (or phone B as any seeded person).

  1. 클럽 tab, the add button, 클럽 만들기. Step through the wizard (a name such as a made-up club name, the next steps) to the end.
  2. Expect to land on the new club's page. Tap the final button once and wait; do not double-tap. Then do it again quickly with a double tap on another club: expect only one club, not two.
  3. From the new club make a first 일정 (the add button, 일정 만들기): expect the review page and one new session. Settles: S11.

C5 Find a club and join by code. Phone B (a person not in the club).

  1. 클럽 tab, the add button, 초대 코드로 가입. Type a wrong code. Expect "이 코드로 찾은 클럽이 없어요. 코드를 다시 확인해 주세요".
  2. Phone A: the club's 초대 코드 (club page menu, or 초대 링크 보내기) shows the code. Type it on phone B. Expect the club's name and a join button; join. Expect to be a member. Settles: S14 (the lookup receipt; the limits are 15 lookups and 5 joins an hour: do not test them).

C6 Club 알림 level. Phone A. On a club you are in: 클럽 알림. Expect a level Sheet that opens in place (the choices include 공지만 and 끔). Pick one; reopen: it is kept.

C7 ★ Photos: the picker and its words. Phone A, a club's 앨범 (or 프로필, edit, photo).

  1. Add a photo. On Android expect the system photo picker and NO camera or microphone question. On iPhone the first time expect a question in Korean: "클럽 사진, 프로필 사진, 영수증을 올리려고 사진 보관함에 접근해요".
  2. Android: phone Settings, Apps, Dabusi, Permissions: expect no Camera permission listed.
  3. Phone B (an ordinary member): a photo that is waiting for approval ("승인 대기") is not visible to B. Settles: S19 (camera permission gone from the config; the merged file is checked only on a device), S20 (web upload re-encode is separate, item K4).

C8 Report and block. Phone A: on a post's ⋯ menu choose 신고 and send. Expect the confirmation. As an official, open 신고 관리 and see it. (Blocking a person is item H5.)

C9 ★ A challenge between clubs (대항전). Phone A, the developer account (an admin of "QA 대항전 상대 클럽"). needs seed.

  1. The proposal waits: open 클럽 대항전 for the opposing club. Expect an incoming proposal with 수락 and 거절. Tap 수락: a dialog "…의 대항전을 수락할까요?"; confirm.
  2. Open "QA 운영 클럽", 클럽 대항전, "대항전 신청": pick an opponent in the picker, see the plan and the period, send. Expect "대항전 신청을 보냈어요". Then withdraw it: dialog "…에 보낸 신청을 철회할까요?" with "철회하면 상대 클럽에 알려 드려요".
  3. Look at "지난 대항전": the settled challenge against "QA 지난 대항전 상대 클럽" shows a result.
  4. Phone B as qaready1 (owner of "QA 대항전 제안 받은 클럽"): the notice "대항전 신청이 왔어요" goes to the owners and admins of the club that RECEIVES a proposal, never to the person who sent it (read from the database's notice rule, private.notify_challenge_club). The proposal waiting in step 1 is addressed to that club, and the developer account is an admin there, so it is the developer account's phone that shows that notice for step 1's proposal, and qaready1's phone that shows it only if you send step 2's proposal to "QA 대항전 제안 받은 클럽". Withdrawing in step 2 sends "대항전이 취소됐어요" to the other club's owners and admins, not to you. Not read from a screen: which clubs the picker offers. Settles: S26 (never ran), S27 (the settle job rewrote old challenges).

C10 An unsent comment or message is kept (new). Phone A, a club post and a chat.

  1. Open a post, type a comment but do not send, go back, open the same post again: the text is still in the box. Open another post: its box is empty. Send the comment: the box empties, and opening the post again shows an empty box.
  2. Open a chat thread, type a message but do not send, go back and reopen it: the text is there; send it and it is gone.
  3. Leave text unsent in one of them, then 로그아웃 and sign in as another account (or the same one): expect both boxes empty. Nothing is saved on the phone itself. Settles: S45 (1).

D. 일정 and RSVP ​

D1 ★ Make a 매치 with a fee and a deposit account. Phone A.

  1. 홈 add button, "클럽 없이 매치로" (or 클럽 page, 일정 만들기). Step through to the fee step. Choose paid and an amount, then the account group (bank, 계좌번호, 예금주).
  2. Expect the review page lists the fee and the account; make it. Expect the new 매치's page.
  3. Open 일정 수정 on it: the fee row is editable until someone pays. Change the title, tap the back arrow: expect "수정을 그만둘까요?" and "바꾼 내용은 저장되지 않아요". Press save instead on a second try: "변경 내용을 저장할까요?" and "참석자 N명에게 일정 변경 알림이 가요". Settles: S22, S23.

D2 Say yes, then no. Phone B (a member of the 매치's club). Open the session, tap 참석하기. Expect the seat (on a free 매치 the first time, the 알림 question of I2 opens over the page: answer it first); tap again to cancel: "참석을 취소할까요?" Confirm. Expect it is cancelled once.

D2b The message never covers the button. Phone B, a free 매치. Tap 참석하기 and press 참석 취소 at once, without waiting. Expect the message "참석 확정됐어요" to sit ABOVE the bottom button, and the press to open its dialog. The same on a wizard step (the message above the primary button) and on a tab page with a FAB (the message above the FAB). Open a page over a tab and trigger a message there: it sits 16 above that page's own bottom button, not higher. Last, with the keyboard up on 채팅 and on 게시글, trigger a message: it sits at the keyboard's top and so may cover the composer; look and tell, this is recorded (NAV-10), not a fault of this step.

D3 Share the session. Phone A on a session: 공유. Expect the phone's share sheet. (The link itself is item K1.)


E. Fees and refunds, on two phones ​

The fee'd 매치 "QA 매치 참가비 15,000" in "QA 매치 모임". needs seed.

E1 ★ A seat holder pays by transfer. Phone B signs in as qaready13.

  1. Open the 매치. Expect "입금 대기 중". Tap 입금 안내.
  2. Expect the Sheet "입금 안내" with 금액 15,000 and the bank, account number and holder, and a "복사" button.
  3. Tap 복사, then paste into a notes app. Expect the number is there and the toast "계좌번호를 복사했어요". (This copy button is new on the phone.)
  4. Close the Sheet, tap "입금했다고 알리기". Expect the page now says "확인 대기 중이에요".
  5. Phone A (host): the 홈 task or the 매치's participant list shows "입금 확인" for qaready13. There is no camera receipt option anywhere. Confirm the payment. Phone B: the notice goes away (paid). Settles: S22, S19 (no camera receipt), the account copy (W5).

E2 A player cancels with more than 24 hours left. Phone B as qaready14 (paid and confirmed).

  1. Cancel the seat. Expect a dialog whose sentence says the fee will be refunded.
  2. Phone A: the 매치 now shows a refund waiting for qaready14: "환불 확인이 아직 남았어요" in the participant list.
  3. Phone B: you cannot join again; the page says "환불이 열린 일정에는 다시 참석할 수 없어요". Settles: S22 (the Dialog's sentence is from the phone's clock; the server decides with its own).

E3 ★ The refund is received. Phone B as qaready15 (the refund is already waiting); phone A host.

  1. Phone B: open the 매치. Expect the notice "환불 대기 15,000원" (or the amount) and "호스트가 보내면 환불받았어요를 눌러 주세요".
  2. Phone A: the participant list shows the refund line; send the money outside the app (a test, nothing is sent).
  3. Phone B: tap 환불받았어요. Expect a dialog "15,000원 환불을 받았나요?" (the amount in it); confirm. Expect "환불을 받았어요" and a "환불 확인됨" badge. The host's list closes the refund. Settles: S21 (the manual rail only), S22.

E4 ★ A cancel inside 24 hours. Phones A and B.

  1. Phone A makes a 매치 that STARTS in under 24 hours with a fee (as D1).
  2. Phone B (any member) joins, then pays and the host confirms (as E1).
  3. Phone B cancels. Expect a dialog whose sentence says the fee is NOT refunded (it is inside the deadline). Phone A: no refund line appears. Then the host can choose "환불 대기로 바꾸기" on that person: the refund line appears and phone B gets the 환불받았어요 path. Settles: S22.

E5 Dues, the ledger and the download. Phone A, club "QA 회비 클럽". needs seed.

  1. 관리, 회비 관리: expect the one-off plan "QA 코트 대관 회비" and who owes. Open 장부: expect an opening balance ("시작 잔액").
  2. "지출 추가": enter a date and an amount, choose a receipt from the album. Expect the balance to equal the opening plus the dated entries.
  3. Tap "장부 내려받기". Expect the phone's share sheet to open with a file; save or open it in a spreadsheet app. Expect the Korean text reads correctly, and the file keeps its name.
  4. Phone B as a member (qaready17): 회비 shows "입금 완료 알리기" sheet with 청구 금액 and 입금한 금액 fields; submit; expect "입금 완료를 알렸어요. 총무 확인을 기다려 주세요." Phone A confirms ("납부 확인됐어요").
  5. Two open charges. The seed's dues club has only the one-off (due in two weeks), so phone A first adds a monthly charge: 관리, 회비 설정, the "납부 주기" row set to "매월", the "금액" row set to an amount (for example 20,000), "납부 기한 (일)" set to 1, then "저장". Then 회비 관리 and "이번 달 회비 만들기", confirm. Phone B as a member (qaready17): the 회비 page leads with the charge with the earlier due date. Here the monthly charge, due on the 1st of this month, is earlier than the one-off, so a pass is the monthly charge first and the one-off "QA 코트 대관 회비" second. (When both fall on the same day the monthly charge leads; the unit test pins that.) Settles: S45 (1). Settles: S18 (the download never ran on a phone), S20.

F. Scores and review ​

F1 ★ A review waiting. Phone A, the finished 매치 "QA 결석 사유 확인 매치". needs seed.

  1. Open it, then the scorecard. Expect two matches: the first has a review waiting, the second was already reviewed and corrected.
  2. Open the first match's review ("점수 검토"). Expect the entered score and the proposed score and the button "이 점수로 바꾸기".
  3. Apply it. Expect the match shows the new score and the review state persists after you leave and return. Settles: S11 (score review pages).

F2 ★ Enter a score and correct it. Phone A (the host) with a 매치 in play, or the chain home_score_verification (the lead can seed it; flow 04 uses it).

  1. From 홈's task or the scorecard, open the score sheet of a match, type 6-4, save. Expect it saved once.
  2. Within ten minutes, the entrant sees "점수 고치기". Change the score and save: ratings move once, the other players get one correction notice.
  3. After ten minutes (or if someone changed it): expect "고칠 수 있는 시간이 지났어요" with "점수가 다르면 검토를 요청해 주세요", or "점수가 바뀌었어요". A player (phone B) can then use "점수 검토 요청".
  4. A score like 6-5 must be refused with its line (the machines check this; look once). Settles: S9 (first correction may take longer; hosted replay time is unmeasured).

F3 A player asks for a review. Phone B as qaready17 on the finished 매치's scorecard: if an own match still allows it, "점수 검토 요청" opens a sheet with "검토 요청". Expect "검토를 요청했어요". If the window is closed, expect "검토를 요청할 수 있는 기간이 지났어요" in a line on the page.

F4 ★ An excusal request (사유 인정 요청). Phone B as qaready9, phone A the developer account (an official). needs seed.

  1. Phone B: open the finished 매치 or the attendance record. For the no-show record, expect a way to ask: the Sheet "사유 인정 요청" with a reason (아픔, 부상 / 가족 일 / 업무 / 교통, 날씨), a note field, and the line telling who can read it. The qaready9 request is already sent: expect the state "확인 중". The health consent (new). In the same Sheet, choose "아픔, 부상": expect an unticked row "건강 관련 사유를 운영진과 공유하는 데 동의해요" with two lines under it (who can see the reason, and "동의하고 싶지 않으면 기타를 골라 메모 없이 보내도 돼요"). "요청 보내기" looks soft: press it without ticking and expect "건강 관련 사유는 동의해야 보낼 수 있어요" on the consent row instead of a sent request. Tick the row and send: it goes. Choose another reason: the consent row disappears and nothing is asked. Every reason's note field says who reads it ("메모는 요청에 답하는 운영진이 읽어요"). A fresh no-show record without a request is needed for the send (the seeded ones all hold a request); if none is left, the lead seeds one. Settles: S45 (5) (counsel reviews this wording).
  2. Phone A: 홈 card or 알림 row for the request; open the record and answer it. Accept: a dialog "…님의 불참 사유를 인정할까요?" with the body "인정하면 불참에서 빠져요. …님에게는 10분 뒤에 알려 드려요"; confirm; expect the toast "사유를 인정했어요", the Tag "운영진이 인정" and the absence off the record. Decline (on another request, qaready9 is the only open one, so decline a fresh one or skip): the dialog "사유 인정 요청을 거절할까요?" with "불참 기록은 그대로 남아요"; the toast "요청을 거절했어요". The person is told ten minutes later, not at once.
  3. Undo: qaready10 was excused a moment ago, so within ten minutes phone A (the official who answered; "답한 사람만 되돌릴 수 있어요" for anyone else) can undo the answer on the record, which shows "되돌릴 수 있는 시간": expect the toast "되돌렸어요" and the earlier status and the penalty back. After ten minutes: "10분이 지나 되돌릴 수 없어요". (The undo button's own label was not read from the Korean table; describe what you see. qa_readiness_rearm_undo re-opens the ten minutes.)
  4. Phone B as qaready11 and qaready12 (answered an hour ago): look only: the states "거절"/"인정됨" and no undo. Settles: S24 (the legal check on the health note is the owner's, not this), S25.

F5 Group stage shape (if you have a tournament). In 대진 짜기 with 7, 13 or 14 teams in groups of 3: expect a Notice about the shape and the make button softened; nothing is made on a press. Not seeded: skip unless you build one.


G. 기록 ​

G1 The 기록 tab. Phone A. Expect the rating Block, the shelves, match cards. Tap a match card: it opens. Look at the names on the cards: a long partner or opponent name wraps onto a second line (batch 59 fixed the match cards that cut it to one line; if you still see a cut name, say which card).

G2 기간 기록 and 하루 기록. From 기록 open a period, then a day. Expect titles "기간 기록" and "하루 기록", the active days, and a match list. A day with no matches reads "이날은 경기가 없어요".

G2b Two kinds of match in the record (batch 66). Phone A, a developer account with friendly and rated matches. (1) 기록: 총 경기 and 승률 count every finished match, friendlies included. (2) 기간 기록 of your own: two rows, 경쟁 and 친선, each with its count and win rate; their counts add up to the period's 총 경기. (3) Open another player's page (from the club ranking): the tiles read 경쟁 경기 and 경쟁 승률, and their 기간 기록 says once that only 경쟁 matches are shown, with no 친선 row. Settles: S51 (b) the counts.

G3 Open another player's record. From a match card or the club ranking, open a person: expect their public record, or "공개하지 않은 기록이에요" when they chose not to share.


H. 프로필 and privacy ​

H1 ★ A stranger sees only what the person chose (the new privacy rule). Phone A, the developer account (you are NOT in "QA 공개 프로필 클럽"). needs seed.

  1. Find qaready23 ("QA 활동 비공개") through 친구 찾기 (type the name) and open the profile. Expect NO main club, NO attendance rate, NO session count and NO last-activity date.
  2. Find qaready24 ("QA 활동 공개") and open the profile. Expect those four facts ARE shown.
  3. Phone B as qaready24, then qaready23: 설정, 공개 범위 설정: the row "주 클럽과 출석 현황" shows their choice. Settles: S37 (F8, the migration 00767 rule; first look at it on a device).

H2 Change your own choice. Phone A: 설정, 공개 범위 설정, row "주 클럽과 출석 현황": change it (전체 공개, 같은 클럽, 친구만). Tap "공개 화면 미리보기": under "모르는 사람" the row shows 보임 or 숨김 to match. Change it back.

H2b Achievements tell their tier without colour (batch 66). Phone A, 프로필, the achievements gallery (or the shelf on 프로필). Expect the earned tiles to differ by ornament: bronze plain, silver a thin frame and one star, gold the frame and two stars, platinum a double frame and three stars; a locked or hidden tile is an outline with no fill, so an earned silver never looks locked. Look at the stars at phone size: five points, none of the frame line crossing a star. Settles: S51 (c) the ornament at phone density.

H3 The trust tier explainer. 프로필: tap the trust tier. Expect the one explainer Sheet. It opens from the club member list too.

H4 Friends. Phone A sends a friend request to phone B's person (친구 찾기, 친구 신청): toast "친구 신청을 보냈어요". Phone B accepts. Both lists show the other.

H5 Blocks. Phone A: 설정, 차단한 사용자: expect "QA 내가 차단한 사람" listed, with 차단 해제. Try to message qaready22 ("QA 나를 차단한 사람"): expect the neutral refusal "지금은 이 분과 대화할 수 없어요" on the page (it does not say who blocked whom). A block hides details and stops offers (new). (1) Phone A opens qaready22's profile (from a search or a member list): the name and the rating still show; the photo is the initials, and region, district, play regions, gender, birth year, 주 클럽 and 출석 현황 are not shown, even if that person had set them to 전체 공개. Then phone B signs in as qaready22 and opens the developer account's profile: the same holds the other way. Compare with a person who has no block (qaready23 or 24). (2) Two phones (batch 66). Phone A (an official) blocks a seeded guest or candidate (the person is found in 멤버 관리, then 설정, 차단한 사용자 does the block) and opens 멤버 관리 again: a guest suggestion or a 가입 후보 row of a person phone A blocked says 차단한 사용자 (the Tag, with 차단을 해제하면 초대할 수 있어요 under the facts) and has no 초대 or 가입 제안 보내기 button. A person who blocked phone A is not suggested at all. Where such a person is still on screen (the 게스트 명단), pressing the offer gives a dialog titled "지금은 이 분께 보낼 수 없어요" over "상대방의 설정이나 계정 상태 때문에 초대를 받을 수 없을 때가 있어요": it never says 차단, and nothing is sent. Settles: S45 (1) and (2), S51 (d).

H6 ★ Withdraw a throwaway account. Phone B signs in as qawithdraw1. needs seed.

  1. 설정, 회원 탈퇴. Expect a page that says what happens: clubs ("모두 나가요"), sessions ("참석이 취소돼요"), fees ("시작 24시간 전까지는 돌려받아요"), records ("사라져요"), recovery ("30일 안에 문의하면 돼요").
  2. Type the phrase it asks for ('탈퇴합니다') and confirm. Expect to be signed out. Signing in again with the same account should not give you the old data.
  3. Phone A: the throwaway's future seat in "QA 탈퇴 연습 매치" is cancelled and the name shows as "탈퇴한 멤버". The 30-day scrub of the sign-in record is a server job and cannot be seen by hand. Not testable by hand: say it is left to the server health read. Settles: S32 (partly), S37.

I. 알림 ​

I1 The 알림 center. Phone A, the bell. Expect section heads, unread rows marked "안 읽음", the filter "처리할 일". Swipe a row to delete: toast "알림을 삭제했어요" with "되돌리기"; tap it to restore. (The swipe finishing is device-only.)

I2 ★ A message and its push. Phones A and B, both signed in, the app in the background on phone A.

  1. The app asks "경기 알림 받으시겠어요?" once: right after the first seat won in a free 매치 (or 예비 seat) while the phone's notification permission was never asked (accept with 알림 받기). Android 13 or later then asks permission: allow. It does not ask again after that, and it never asks in a phone's browser.
  2. Phone B: 메시지, send a typed message to the developer account (if a request is needed it shows under 메시지 요청 on phone A).
  3. Phone A: expect a push; tap it. Expect the app opens on that thread.
  4. With TalkBack (Android) or VoiceOver (iPhone) on, focus a chat bubble in that thread. Expect it reads the message and then announces that a long press opens the message menu ("메시지 메뉴"); the long press opens it. Settles: S11, S34.

I3 Notification settings. 설정, 알림 설정: the master 푸시 알림, 방해 금지 시간 (the line says deposit notices still come), the families, and per-club levels (공지만, 끔). Turn one off and on: it is kept.

I4 Sign-out and the next person's push. Phone A: 로그아웃 (online). Sign in as another account. Expect no leftover data from the first account on the first screen, and phone A no longer receives the first account's pushes. (Offline sign-out leaves the old token on the server until the next registration: S34; optional: sign out in airplane mode, then see whether a push for the old account reaches the phone.) Settles: S34.

I5 The notification colour. Android 12 or later: trigger a push and look at the small icon in the light and dark shade. Expect a green icon readable on both.


J. 설정 ​

J1 The version row. 설정, 앱 버전 reads 0.12.0. Press the row seven times: "개발자 모드" appears (the dev panel). Only the developer account sees it by default.

J2 Sign out and sign in as another person. 로그아웃, then sign in as a seeded person. Expect the first screen shows the new person's data only.

J3 Legal pages. 설정, 개인정보 처리방침: the page opens; "내 데이터" offers the download. (The download is a share sheet on a phone.)


K1 ★ A shared session link, in a phone browser and KakaoTalk. Phone A: open a session, 공유, send the link to yourself in KakaoTalk (or a notes app).

  1. Open it in the phone's browser. Expect a page with the link card: the title, the date and place. Open a link with a made-up id (change a few letters): expect the not-found page.
  2. Open the link in KakaoTalk's own browser. Expect the same. Settles: S13 (the share page's content is drawn in the browser), S28.

K2 The invite page while signed out. Take an invite link of a club from phone A (the club's 초대 링크 보내기), open it in the phone's browser while signed out of the web app. Expect the club's name and facts ABOVE the sign-in band. A made-up code shows the page as before, without a club. In KakaoTalk's browser as well. Settles: S28, S14.

K3 Open a link in the app. With the app installed, tap a session link in a message. Expect the app opens on that session (or the join page for an invite). Press back: expect 홈, not a blank page.

K4 A photo from the web. In a phone browser on the web app (sign in as the developer account), upload a geotagged photo as a club photo or avatar. Expect it works. Checking that the stored photo carries no location needs a tool: tell the lead. (On Safari, a HEIC photo too.) Settles: S20.


L. When things go wrong ​

L1 Offline, and the one strip. Phone A on 홈.

  1. Turn on airplane mode. Within about two to seven seconds expect ONE strip across the app: "오프라인이에요" (the app says it only after a few failures and a failed check), with "연결되면 자동으로 다시 불러와요".
  2. Try a write that cannot wait (for example 클럽 만들기, or sending a report): expect the control held with the strip's sentence, not a crash.
  3. Turn airplane mode off. Expect the strip leaves by itself and the page reloads. Settles: S11, S17.

L2 A queued write. Phone B, airplane mode on. Tap 참석하기 on a session. Expect "N건 대기 중" on the strip. Turn airplane mode off. Expect the RSVP is sent ONCE (check the roster has one entry, not two).

L3 A refused write shows on its page. Phone B. Do something the server will refuse: for example join with a wrong invite code (C5), or ask a second excusal for the same absence. Expect the refusal as a line on the page or a dialog the page opens, in plain Korean words, never a toast that disappears.

L4 A lapsed sign-in. Needs the lead. Phone B is signed in with the app open. The lead ends that account's sign-in sessions on the server (the same function a withdrawal uses). Phone B: pull to refresh or open another tab. Expect the sign-in page or a clear message that the sign-in is unavailable, and NEVER empty lists shown as if you had no data. Settles: S11 (new in this build: a request that needs a person is not sent as a stranger).

L5 Pages that hide offline. Phone A, airplane mode on, open 회비 관리 or 장부 of a club you opened earlier. Expect the offline page, not an old balance. Your own dues and the club home feed may still show.

L6 A page that is gone. Open a session or club from an old link after it was deleted or cancelled: expect a not-found page with a way back ("클럽으로" or similar), not a blank.


The twenty ★ items, in order ​

A1, A2, A5, A7, C1, C2, C4, C7, C9, D1, E1, E3, E4, F1, F2, F4, H1, H6, I2, K1 — with K2, L1, L2, L3 and L4 as the next five if time remains.

Not covered, on purpose ​

The card payment path (portone-webhook and verify-portone-payment are not on hosted). A waitlisted viewer of a 매치's account page (no full session is seeded). A level-up Notice (needs a rating near a boundary). The settle job's notices and the hosted 30-day scrub (server jobs). iPhone (no iOS build exists). Signed updates (optional, pre-build step 8).

After the list ​

Send the marked list and screenshots as the post-build checklist says. The lead then reads the phones' error reports and the server's health and enters the results in release evidence, section "What only a device can show".

Markdown remains the source of truth. Run yarn docs:check before handoff.