Ranking touch-drag fix on iOS + direct DB connection docs - #50
Merged
Conversation
survey-core defaults ranking's longTap to true, so on iOS Safari the first touch on a ranking item is treated as a scroll gesture and the page scrolls instead of starting the drag — reorder is unreachable on iPhone. SurveyJS's own docs recommend disabling longTap when users naturally swipe-to-drag. Disable it at the schema level via a one-shot Serializer side-effect (new surveyInit.ts) imported by both code paths that mount a Survey: the respondent runner and the admin preview. Idempotent and explicit about the shape it expects, so a future survey-core upgrade that renames the property fails loudly here rather than at the assignment site. Regression test asserts the live default — survey-core resetting it would silently re-break iPhone reordering. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Inline the analyst/reviewer connect flow that previously just pointed at docs/verification/m7.6-demo-to-prod.md: enable the opt-in TCP proxy, grab the role password from a tofu output, connect with psql. Calls out the choice between stele_analyst (marts) and stele_pii_reviewer (pii), and the gotchas worth knowing up front — the postgresql:// vs. postgresql+psycopg:// driver tag, the database_name default, and the NOINHERIT SET ROLE step for a per-user credential minted by the M3.5 provisioning CLI. Demo seed + secret rotation stay as a pointer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR bundles two small, unrelated updates: (1) a frontend SurveyJS initialization tweak to make ranking drag/reorder usable on iOS Safari, and (2) expanded infra documentation for direct Postgres access via Railway’s opt-in TCP proxy.
Changes:
- Frontend: introduce a
surveyInitside-effect module that sets SurveyJS rankinglongTapdefault tofalse, and load it anywhere aSurveyis mounted. - Frontend: add a Vitest regression test asserting the
longTapdefault remainsfalse. - Infra: expand
infra/README.mdwith step-by-step guidance for enabling the Postgres proxy and connecting viapsql.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| infra/README.md | Adds direct-Postgres connection instructions (proxy enable/disable + psql gotchas). |
| frontend/src/SurveyRunner.tsx | Imports surveyInit for respondent runner path. |
| frontend/src/admin/SurveyPreview.tsx | Imports surveyInit for admin preview path. |
| frontend/src/surveyInit.ts | Sets SurveyJS ranking longTap serializer default to false with a fail-fast check. |
| frontend/src/surveyInit.test.ts | Regression test ensuring longTap default remains disabled. |
Comment on lines
+128
to
+129
| echo 'enable_postgres_proxy = true' >> terraform.tfvars | ||
| tofu apply |
Comment on lines
+132
to
+144
| # 2. Grab the role password. | ||
| tofu output -raw stele_analyst_password # marts (the warehouse) | ||
| tofu output -raw stele_pii_reviewer_password # pii (free-text review) | ||
|
|
||
| # 3. Connect. | ||
| psql "postgresql://stele_analyst:<password>@<host>:<port>/stele" | ||
| ``` | ||
|
|
||
| Pick the role by what you need to read: `stele_analyst` reaches `marts` only, | ||
| `stele_pii_reviewer` reaches `pii` only — that one-schema-each ceiling is what | ||
| keeps a leaked credential low-stakes (CLAUDE.md *Schemas* table). Both group | ||
| roles are LOGIN and hold the schema grant directly, so no `SET ROLE` step is | ||
| needed. |
Comment on lines
+158
to
+159
| When you're done, set `enable_postgres_proxy = false` and `tofu apply` to close | ||
| the public endpoint. |
- Use `tofu apply -var 'enable_postgres_proxy=true/false'` for both flip and unflip so re-running stays idempotent (the prior `echo … >> terraform.tfvars` appended duplicate assignments on a second pass) and matches the house style in "Rolling out a new build" (-var deploy_latest=true). - Split into "Operator shortcut" + "Per-user logins" subsections. The former spells out that the group-role passwords from tofu state are operator-wide secrets with no per-person audit trail — don't hand them out. The latter promotes the M3.5 provisioning CLI flow from a buried gotcha to a named peer subsection, which is the auditable/revocable path for anyone else. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two unrelated small changes, bundled at the operator's request.
1. Fix ranking touch-drag on iOS (GH #49)
survey-core's
rankingdefaultslongTap=true, so on iOS Safari the first touch on a ranking item is treated as a scroll gesture and the page scrolls instead of starting the drag — reorder is unreachable on iPhone. SurveyJS's own docs recommend disablinglongTapwhen users naturally swipe-to-drag.frontend/src/surveyInit.tstoggles the default once viaSerializer.findProperty('ranking', 'longTap').defaultValue = false. Idempotent; the explicit null-check makes a future survey-core property rename fail loudly here rather than at the assignment site.Survey:SurveyRunner.tsx(respondent) andadmin/SurveyPreview.tsx(admin preview).2. Document direct Postgres access in
infra/README.mdInlines the analyst/reviewer connect flow that previously just pointed at
docs/verification/m7.6-demo-to-prod.md: enable the opt-in TCP proxy, grab the role password from atofu output, connect withpsql. Calls out the choice betweenstele_analyst(marts) andstele_pii_reviewer(pii), and the gotchas — thepostgresql://vspostgresql+psycopg://driver tag, thedatabase_namedefault, and the NOINHERITSET ROLEstep for per-user credentials. Demo seed + secret rotation stay as a pointer.Test plan
cd frontend && npm run lint— cleancd frontend && npm run typecheck— cleancd frontend && npm test— 140 tests across 25 files pass, incl. the newsurveyInitregression test🤖 Generated with Claude Code