Skip to content

[survey2ddi 4/6] LimeSurvey RemoteControl adapter + formtransform limesurvey command #13

Description

@jstet

Step 4 of 6 for the survey2ddi retirement. Plan: HANDOVER_SURVEY2DDI.md. Depends on the normalize_responses port for its transform subcommand; the list / pull half is independent.

Why

limesurvey2ddi in CorrelAid/survey2ddi pulls a survey's structure and responses over LimeSurvey's RemoteControl API and converts them. The conversion is duplicated here; the pull is not.

What to port

limesurvey2ddi/client.py + lstsv.py:

  • JSON-RPC over RemoteControl (/admin/remotecontrol): get_session_key → calls → release_session_key. RPC errors come back in the result body, not as HTTP status codes — the error shape and session expiry are the parts that need care, and the reason this is a bigger issue than the Kobo one.
  • list_surveys(), get_responses(survey_id), and the survey-structure TSV export that feeds lstsvToDdiXml.
  • pull(survey_id, out) writing the structure TSV + responses.

CLI:

formtransform limesurvey list
formtransform limesurvey pull <survey_id> -o output/
formtransform limesurvey transform <survey_id> -o output/   # pull + lstsv2ddi + data CSV

Env vars keep their current names so existing .env files work: LIME_SERVER_URL, LIME_USERNAME, LIME_PASSWORD, each overridable by a flag.

Prior art in this repo

tests/live/ already drives this exact API — through the citric Python client, via codegen.limesurvey_stack (session handling, wait_until_ready, import+activate). Read that for the call sequence before writing the RPC layer.

Worth deciding as part of this issue: once a TS client exists, should the live suite exercise it instead of citric? That would make the client's session handling continuously tested against a real LimeSurvey rather than only in unit tests with mocked responses. Not required to close this, but say which way you went and why.

Constraints

  • Node-only; not re-exported from src/index.ts (same rule as the Kobo adapter).
  • Never log credentials or the session key.
  • Always release the session key, including on error paths.

Acceptance criteria

  • Session acquire/release around every call, released on failure too
  • RPC-level errors surface as real errors, not silent nulls
  • list / pull / transform match the Python CLI's behaviour and env vars
  • Decision recorded on whether tests/live/ now uses the TS client
  • Browser entry unchanged

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions