feat: improve form response experience
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# ADR 0001: Form response UX and answer representation
|
||||
|
||||
- Status: Accepted
|
||||
- Date: 2026-07-24
|
||||
|
||||
## Context
|
||||
|
||||
The form flow supports one Discord-linked submission per person, local draft recovery,
|
||||
response updates, deletion, role-based access, and four question types. The previous
|
||||
interface blurred local drafts and server submissions, hid role-gated forms behind a
|
||||
404 before login, front-loaded long descriptions, and represented checkbox answers as
|
||||
comma-separated text.
|
||||
|
||||
## Decision
|
||||
|
||||
1. Authentication happens before authorization. Anonymous visitors to a valid direct
|
||||
form link see the Discord login prompt; authenticated visitors without permission
|
||||
continue to receive the not-found state.
|
||||
2. Drafts remain browser-local and are explicitly described as saved on this device.
|
||||
Draft storage contains both normal answers and free text entered for “Other”.
|
||||
3. Long form descriptions remain available in full but start collapsed behind a
|
||||
clearly labelled rules disclosure.
|
||||
4. The UI distinguishes a new answer, an editable submitted answer, and a closed form.
|
||||
When a form closes, an existing response is read-only but can still be deleted.
|
||||
5. Question text programmatically labels its control. Radio and checkbox choices use
|
||||
semantic fieldsets, and image enlargement uses a keyboard-accessible button.
|
||||
6. Checkbox answers are stored as JSON arrays in the existing text column. Readers
|
||||
retain a fallback for legacy comma-separated values, so no database migration is
|
||||
required.
|
||||
7. Server Actions independently validate authentication, form access, required
|
||||
answers, question ownership, answer shape, and allowed choices.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Existing checkbox answers remain readable, while new answers can safely contain
|
||||
commas.
|
||||
- Local drafts do not follow a person to another device; the interface says so.
|
||||
- Users must authenticate before seeing form questions.
|
||||
- Closing a form prevents new submissions and updates but does not prevent a person
|
||||
from deleting their existing response.
|
||||
- A future cross-device draft feature should introduce a server-side draft entity
|
||||
rather than changing the meaning of the current local draft.
|
||||
@@ -0,0 +1,36 @@
|
||||
# Glossary
|
||||
|
||||
## Form
|
||||
|
||||
An administrator-authored questionnaire with an open or closed state and optional
|
||||
Discord role restrictions.
|
||||
|
||||
## Question
|
||||
|
||||
An ordered prompt within a form. Its answer shape is text, long text, one choice, or
|
||||
multiple choices.
|
||||
|
||||
## Local draft
|
||||
|
||||
Unsubmitted or in-progress answers stored in the current browser for one form. A local
|
||||
draft is device-specific and is not authoritative.
|
||||
|
||||
## Submission
|
||||
|
||||
The server-saved answer set for one form and one Discord account. A person can have at
|
||||
most one submission per form.
|
||||
|
||||
## Update
|
||||
|
||||
A replacement of the answer values in an existing submission. The previous values are
|
||||
retained in edit history.
|
||||
|
||||
## Other answer
|
||||
|
||||
Free text associated with an explicit “Other” choice. Selecting “Other” requires
|
||||
non-empty text, even when the overall question is optional.
|
||||
|
||||
## Closed form
|
||||
|
||||
A form that no longer accepts new submissions or updates. A person with an existing
|
||||
submission may still read or delete it.
|
||||
Reference in New Issue
Block a user