# Connector Dev Stack This directory keeps local Docker Compose assets for GovOPlaN file connector development. The stack is intentionally separate from production deployment and binds services to localhost high ports. ## Start ```bash cd /mnt/DATA/git/govoplan-files/dev/connectors cp .env.example .env mkdir -p data/smb data/webdav docker compose up -d nextcloud nextcloud-db webdav smb minio docker compose up -d seafile-db seafile-memcached seafile ``` If the SMB service was already running before a compose change, recreate it so the image and share configuration are applied: ```bash docker compose rm -sf smb docker compose up -d --build smb ``` Endpoints: - Nextcloud: `http://127.0.0.1:9081`, WebDAV root `http://127.0.0.1:9081/remote.php/dav/files/admin/` - Seafile: `http://127.0.0.1:9082`, WebDAV root `http://127.0.0.1:9082/seafdav/` - WebDAV: `http://127.0.0.1:9083` - SMB: `smb://127.0.0.1:1445/files` - MinIO/S3 API: `http://127.0.0.1:9000`, console `http://127.0.0.1:9001` The local fixture data under `data/` is ignored by git. ## GovOPlaN Profile Config Connector profiles are read from `GOVOPLAN_FILES_CONNECTOR_PROFILES_JSON` or `GOVOPLAN_FILES_CONNECTOR_PROFILES_FILE`. This deployment-owned configuration may reference environment variables only when their exact names are listed in `GOVOPLAN_CONNECTOR_SECRET_ENV_ALLOWLIST`; profile API responses expose only the credential source and configured state. Example local profile file: ```json { "profiles": [ { "id": "dev-seafile", "label": "Dev Seafile", "provider": "seafile", "endpoint_url": "http://127.0.0.1:9082", "scope_type": "system", "credential_mode": "basic", "username": "admin@example.local", "password_env": "SEAFILE_ADMIN_PASSWORD", "capabilities": ["browse", "import"], "metadata": { "webdav_endpoint_url": "http://127.0.0.1:9082/seafdav/" }, "policy": { "allow": { "providers": ["seafile"] } } }, { "id": "dev-nextcloud", "label": "Dev Nextcloud", "provider": "nextcloud", "endpoint_url": "http://127.0.0.1:9081/remote.php/dav/files/admin/", "scope_type": "system", "credential_mode": "basic", "username": "admin", "password_env": "NEXTCLOUD_ADMIN_PASSWORD", "capabilities": ["browse", "import"], "policy": { "allow": { "providers": ["nextcloud", "webdav"] } } }, { "id": "dev-webdav", "label": "Dev WebDAV", "provider": "webdav", "endpoint_url": "http://127.0.0.1:9083", "scope_type": "system", "credential_mode": "basic", "username": "govoplan", "password_env": "WEBDAV_PASSWORD", "capabilities": ["browse", "import"], "policy": { "allow": { "providers": ["webdav"] } } }, { "id": "dev-smb", "label": "Dev SMB", "provider": "smb", "endpoint_url": "smb://127.0.0.1:1445/files", "scope_type": "system", "credential_mode": "basic", "username": "govoplan", "password_env": "SMB_PASSWORD", "capabilities": ["browse", "import"], "policy": { "allow": { "providers": ["smb"] } } }, { "id": "dev-s3", "label": "Dev MinIO", "provider": "s3", "endpoint_url": "http://127.0.0.1:9000", "base_path": "", "scope_type": "system", "credential_mode": "basic", "username": "govoplan", "password_env": "MINIO_ROOT_PASSWORD", "capabilities": ["browse", "import"], "metadata": { "bucket": "govoplan", "region": "us-east-1", "path_style": true, "verify_tls": false }, "policy": { "allow": { "providers": ["s3"] } } } ] } ``` Start GovOPlaN with: ```bash export GOVOPLAN_FILES_CONNECTOR_PROFILES_FILE=/mnt/DATA/git/govoplan-files/dev/connectors/profiles.local.json export GOVOPLAN_CONNECTOR_SECRET_ENV_ALLOWLIST=SEAFILE_ADMIN_PASSWORD,NEXTCLOUD_ADMIN_PASSWORD,WEBDAV_PASSWORD,SMB_PASSWORD,MINIO_ROOT_PASSWORD export GOVOPLAN_CONNECTOR_ALLOW_PRIVATE_NETWORKS=true ``` ## Smoke Test Run the connector helper smoke checks from an environment where `govoplan-files` and `httpx` are importable: ```bash cd /mnt/DATA/git/govoplan-files/dev/connectors /mnt/DATA/git/govoplan-core/.venv/bin/python smoke.py ``` The script reads `.env` from this directory when present and seeds tiny WebDAV, Nextcloud, SMB, and MinIO fixtures. WebDAV and Nextcloud are browsed and imported through the pinned connector transport. SMB and S3 product access deliberately fails closed until their SDK transports support peer pinning, so their fixtures are retained for transport development and reported as expected optional skips. The `--require-smb` and `--require-s3` switches are useful only while developing that transport support and currently make the smoke check fail by design. SMB smoke checks need the optional Python dependency in the environment running the script: ```bash /mnt/DATA/git/govoplan-core/.venv/bin/python -m pip install -e /mnt/DATA/git/govoplan-files[smb] ``` S3 smoke checks need the optional boto3 dependency in the environment running the script: ```bash /mnt/DATA/git/govoplan-core/.venv/bin/python -m pip install -e /mnt/DATA/git/govoplan-files[s3] ``` The SMB service is built from `dev/connectors/smb/` so the development share is deterministic: one `files` share backed by `data/smb`, with the credentials from `.env`. The SMB image runs as the non-root `govoplan` user with UID/GID `1000` and listens on unprivileged container port `1445`. The default host endpoint remains `smb://127.0.0.1:1445/files`. `SMB_USER` must stay `govoplan` unless the image is rebuilt with a matching user; `SMB_PORT` must be `1024` or higher. `SMB_PASSWORD` is applied when the image is built, so rebuild the `smb` service after changing it in `.env`.