Skip to content

Feature: Forms #659

@qwerzl

Description

@qwerzl

So uh, I'm not familiar with designing a schema to store form responses with relational database. But here's what I've collected by far:

Zod ⇔ JSON Schema:

P.S. The library's README suggests using eval(). Use new Function() instead.

Form Rendering

  • Auto Form. Convert the stored JSON schema back to zod.

Database design

e.g.:

model Form {
  id                String   @id @default(dbgenerated("gen_random_uuid()"))
  creationTimestamp DateTime @default(now())
  user              User     @relation(fields: [userId], references: [id])
  userId            String
  club              Club     @relation(fields: [clubId], references: [id])
  clubId            Int
  formSchema        String // A JSON Schema converted from Zod

  FormResponse FormResponse[]
}

model FormResponse {
  id                String   @id @default(dbgenerated("gen_random_uuid()"))
  creationTimestamp DateTime @default(now())
  user              User     @relation(fields: [userId], references: [id])
  userId            String
  form              Form     @relation(fields: [formId], references: [id])
  formId            String
  response          Json // A JSON object that conforms to the schema as designed in the form
}

It's best to validate the response data being fed into the database every INSERT or UPDATE.

Resources:

  • pg_jsonschema
  • Enable postgres extensions in Prisma
  • We need a trigger at postgresql every UPDATE or INSERT. Check constraints won't work because they don't support subqueries. eg:
    CREATE OR REPLACE FUNCTION validate_formresponse_schema() 
    RETURNS TRIGGER AS $$
    BEGIN
        -- Validate that the meta field matches the schema
        PERFORM jsonb_matches_schema(
            NEW.form.formSchema,
            NEW.response
        );
    
        -- If validation passes, proceed with the insert/update
        RETURN NEW;
    END;
    $$ LANGUAGE plpgsql;
    CREATE TRIGGER validate_formresponse_schema_trigger
      BEFORE INSERT OR UPDATE ON FormResponse
      FOR EACH ROW
      EXECUTE FUNCTION alidate_formresponse_schema();

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions