{"id":49788224,"url":"https://github.com/radical-data/primer-paso","last_synced_at":"2026-05-12T02:31:48.745Z","repository":{"id":351775451,"uuid":"1211695565","full_name":"radical-data/primer-paso","owner":"radical-data","description":"Intake screener for Spain's 2026 extraordinary regularisation process","archived":false,"fork":false,"pushed_at":"2026-05-05T21:43:53.000Z","size":1203,"stargazers_count":2,"open_issues_count":17,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-05T22:28:00.985Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://primerpaso.org","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/radical-data.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-15T16:49:52.000Z","updated_at":"2026-05-05T21:43:55.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/radical-data/primer-paso","commit_stats":null,"previous_names":["radical-data/regularisation-intake"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/radical-data/primer-paso","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radical-data%2Fprimer-paso","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radical-data%2Fprimer-paso/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radical-data%2Fprimer-paso/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radical-data%2Fprimer-paso/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/radical-data","download_url":"https://codeload.github.com/radical-data/primer-paso/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radical-data%2Fprimer-paso/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32920954,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-11T17:09:15.040Z","status":"online","status_checked_at":"2026-05-12T02:00:06.338Z","response_time":102,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-12T02:31:47.451Z","updated_at":"2026-05-12T02:31:48.732Z","avatar_url":"https://github.com/radical-data.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Primer Paso\n\nA pnpm monorepo for a multilingual, server-first intake screener for Spain's 2026 extraordinary regularisation process and related organisation workflows.\n\n## What it does\n\n- guides people through a one-question-per-page journey\n- stores progress in a session cookie\n- shows a check-answers step before the result\n- runs triage rules to produce a cautious next-step outcome\n- supports assisted completion and language switching\n- uses locale-prefixed URLs for every public route (`/es/...`, `/en/...`, `/fr/...`, `/ar/...`)\n\n## Development\n\n```sh\nmise install\nmise x -- pnpm install --frozen-lockfile\nmise x -- pnpm dev\n```\n\nThe default `pnpm dev` command runs the public app.\n\nTo run apps explicitly:\n\n```sh\npnpm dev:public\npnpm dev:org\n```\n\nTo check that the analytics environment contract is satisfied:\n\n```sh\nmise run analytics:env:check\n```\n\n## Checks\n\n```sh\npnpm run check\npnpm run typecheck\npnpm test\n```\n\n`pnpm test` loads committed `.env.test` for the public app so Matomo-related unit tests match CI (see `apps/public/package.json` `test` script).\n\n## Build\n\n```sh\npnpm build\npnpm build:public\npnpm preview\n```\n\n## Project shape\n\n- apps/public — public Primer Paso service\n- apps/org-portal — authenticated organisation portal placeholder\n- packages/certificate — shared certificate model and PDF generation package placeholder\n- packages/auth — shared role and permission model placeholder\n- packages/db — shared persistence package placeholder\n- packages/config — shared app configuration placeholder\n- packages/ui — shared UI package placeholder\n- docs/ — design spec, journey, triage rules, ADRs\n\n## Notes\n\n- the core flow uses standard HTML forms and SvelteKit form actions\n- the app is configured for Netlify deployment\n- this service is triage, not a legal determination\n\n## Certificate handoff storage\n\nThe public certificate handoff flow stores the certificate draft server-side and places\nonly an opaque token in the handoff URL/QR code.\n\nTo enable it:\n\n1. apply `packages/db/migrations/001_certificate_handoffs.sql` to Postgres\n2. set `PRIVATE_DATABASE_URL`\n3. set `PUBLIC_CERTIFICATE_HANDOFF_ENABLED=true`\n4. set `PUBLIC_ORG_PORTAL_URL`\n\nThe raw token is never stored. The database stores only a SHA-256 token hash.\n\n## Local organisation portal testing\n\nThe organisation portal uses Supabase Auth magic links. It is not open registration:\nthe email must already exist in `organisation_members`, and the same address must\nbe able to sign in via your Supabase project.\n\nFor local testing, set:\n\n```sh\nPRIVATE_DATABASE_PROVIDER=supabase\nPRIVATE_DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres\nPUBLIC_CERTIFICATE_HANDOFF_ENABLED=true\nPUBLIC_ORG_PORTAL_URL=http://localhost:5174\nPUBLIC_SUPABASE_URL=http://127.0.0.1:54321\nPUBLIC_SUPABASE_PUBLISHABLE_KEY=your-local-anon-key\nPRIVATE_ORG_PORTAL_CUSTOM_SMTP_CONFIGURED=false\n```\n\nFor local Supabase, run `supabase status` and copy the local anon key into\n`PUBLIC_SUPABASE_PUBLISHABLE_KEY`. Magic links return to `/auth/confirm`.\nFor deployed environments, set `PRIVATE_ORG_PORTAL_CUSTOM_SMTP_CONFIGURED=true`\nand use custom SMTP in the Supabase dashboard.\n\nSee `docs/supabase-org-auth.md` for the Supabase dashboard setup.\n\nReset and seed the local Supabase database:\n\n```sh\npnpm db:reset\n```\n\nSeed a local collaborating organisation and test users:\n\n```sh\npnpm db:seed:local-org-portal\n```\n\nThe seed command loads the repository-root `.env` automatically. If you run the\npackage script directly from `packages/db`, it loads `../../.env`.\n\nSeeded local member emails:\n\n```txt\nadmin@example.invalid\nvolunteer@example.invalid\nsigner@example.invalid\n```\n\nUse any of those emails on the organisation portal sign-in page; Supabase will\nsend a sign-in link if the project is configured.\n\n## Supabase Auth setup for the organisation portal\n\nThe organisation portal uses Supabase Auth for email magic-link sign-in, then maps\nthe authenticated Supabase user email to an active row in `organisation_members`.\nSupabase authenticates the inbox. Primer Paso still owns organisation membership,\nroles, and permissions.\n\n### 1. Authentication -\u003e URL Configuration\n\nSet:\n\n```txt\nSite URL: https://org.primerpaso.org\nRedirect URL: https://org.primerpaso.org/auth/confirm\n```\n\nAdd preview and local callback URLs as needed, for example:\n\n```txt\nhttp://localhost:5174/auth/confirm\n```\n\nOnly add origins you actually use. Avoid wildcard redirects for production.\n\n### 2. Authentication -\u003e Providers -\u003e Email\n\nEnable email sign-ins.\n\nUse the magic-link email flow. The application passes `emailRedirectTo` when it\nrequests the link, so links should return to:\n\n```txt\n/auth/confirm\n```\n\nThe confirmation route exchanges the Supabase token hash for a session and then\nchecks that the email belongs to an active organisation member.\n\n### 3. Authentication -\u003e Emails -\u003e SMTP Settings\n\nConfigure a real SMTP provider before deployed use. Do not rely on Supabase's\ndefault email service for production or previews.\n\nSet this only after SMTP is configured and tested:\n\n```sh\nPRIVATE_ORG_PORTAL_CUSTOM_SMTP_CONFIGURED=true\n```\n\nFor local development against a hosted Supabase project, this can stay false:\n\n```sh\nPRIVATE_ORG_PORTAL_CUSTOM_SMTP_CONFIGURED=false\n```\n\n### 4. Security settings\n\nRecommended Supabase project settings for this repository:\n\n- Enable Data API: optional. The current app does not need it for server-side\n  database access, because it uses the Postgres connection directly.\n- Automatically expose new tables and functions: disable.\n- Enable automatic RLS: enable.\n\nEven if the Data API is not used now, keeping RLS enabled by default is a useful\ndefence against future accidental exposure.\n\n### SMTP provider recommendation\n\nUse Postmark for the organisation portal.\n\nIt is a better fit for this workflow because the portal sends low-volume,\nhigh-trust transactional email where deliverability and clear operational\ndebugging matter more than marketing features. Resend is also good, especially\nfor developer experience, but Postmark is the safer default for magic-link auth\nemails in a public-interest service.\n\nBasic setup:\n\n1. Create a Postmark account.\n2. Add and verify the sending domain, for example `primerpaso.org`.\n3. Add the DNS records Postmark gives you for SPF, DKIM, and return-path/bounce\n   handling.\n4. Create a server/message stream for transactional email.\n5. Copy the SMTP host, port, username, and password into Supabase:\n   Authentication -\u003e Emails -\u003e SMTP Settings.\n6. Send a test magic link from the organisation portal.\n7. Set `PRIVATE_ORG_PORTAL_CUSTOM_SMTP_CONFIGURED=true` in deployed environments.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fradical-data%2Fprimer-paso","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fradical-data%2Fprimer-paso","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fradical-data%2Fprimer-paso/lists"}