{"id":49216641,"url":"https://github.com/mikko-lab/a11y-lead-engine","last_synced_at":"2026-05-03T22:01:06.454Z","repository":{"id":349413938,"uuid":"1193914976","full_name":"mikko-lab/a11y-lead-engine","owner":"mikko-lab","description":"A11y-myyntikone","archived":false,"fork":false,"pushed_at":"2026-05-03T20:03:12.000Z","size":295,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-03T21:27:28.720Z","etag":null,"topics":["accessibility","axe-core","lead-generation","nodejs","playwright","typescript","wcag","wordpress"],"latest_commit_sha":null,"homepage":null,"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/mikko-lab.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":null,"security":null,"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-03-27T18:02:07.000Z","updated_at":"2026-05-03T20:08:54.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mikko-lab/a11y-lead-engine","commit_stats":null,"previous_names":["mikko-lab/a11y-lead-engine"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mikko-lab/a11y-lead-engine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikko-lab%2Fa11y-lead-engine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikko-lab%2Fa11y-lead-engine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikko-lab%2Fa11y-lead-engine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikko-lab%2Fa11y-lead-engine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mikko-lab","download_url":"https://codeload.github.com/mikko-lab/a11y-lead-engine/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikko-lab%2Fa11y-lead-engine/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32586187,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["accessibility","axe-core","lead-generation","nodejs","playwright","typescript","wcag","wordpress"],"created_at":"2026-04-24T00:40:05.732Z","updated_at":"2026-05-03T22:01:06.441Z","avatar_url":"https://github.com/mikko-lab.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# A11Y Lead Engine\n\nAutomaattinen saavutettavuusskanneri ja liidien hallintajärjestelmä WordPress-sivustoille. Skannaa sivustot WCAG 2.2 AA -standardin mukaan, generoi AI-yhteenvedon johdolle ja lähettää personoidun sähköpostin raporttilinkillä.\n\n---\n\n## Ominaisuudet\n\n- **Pre-filter** — nopea esitarkistus ennen skannausta (kieli, CTA, WordPress-tunnistus, suurten toimijoiden blocklist)\n- **WCAG 2.2 AA -skannaus** — axe-core + Playwright, pisteet 0–100\n- **AI-yhteenveto** — Claude Haiku generoi selkokielisen tiivistelmän johtajalle suomeksi\n- **Web-raportti** — asiakkaalle lähetettävä raporttisivu (`/r/:token`), ei PDF-liitettä\n- **Sähköpostilähetys** — personoitu HTML-viesti, positiivinen sävy, GDPR-opt-out\n- **Sähköpostin etsintä** — Hunter.io → WP REST API → sivuston scrape (footer-first)\n- **YTJ-integraatio** — yrityksen nimi, Y-tunnus ja TOL-toimialakoodi\n- **Kauppalehti-integraatio** — liikevaihto ja henkilöstömäärä\n- **Toimialasuodatus** — kohdista ajo valituille TOL-toimialoille\n- **Lähdeseuranta** — tallentaa mistä hausta kukin liidi löytyi\n- **Lead-numero** — juokseva #-numero helpottaa asiakkaaseen viittaamista\n- **GDPR opt-out** — asiakas voi kieltäytyä lisäviesteistä (`/opt-out/:token`)\n- **Muutosseuranta** — seuraa domainien HTML-muutoksia\n- **Web-dashboard** — leadit, tilastot, uuden ajon käynnistys, live-loki\n- **Sähköpostin manuaalinen hallinta** — lisää tai muokkaa asiakkaan sähköpostiosoite suoraan dashboardissa ilman lähetystä\n- **Finlex-skräpperi** — hakee saavutettavuuteen liittyvät oikeustapaukset Suomesta (Finlex)\n- **Rechtspraak-integraatio** — hakee WCAG/toegankelijkheid-tapaukset Hollannin tuomioistuimista (virallinen avoin API)\n- **Court Ticket -agentti** — Claude analysoi oikeustapaukset automaattisesti ja luo myyntitiketit: organisaatio, prioriteetti 0–10, ehdotettu yhteydenottokulma\n- **Kanteet-dashboard** — ⚖️ erillinen välilehti oikeuskanteille, status-seuranta (Uusi → Kontaktoitu → Konvertoitu)\n\n---\n\n## Pikastartti\n\n### Vaatimukset\n\n- Node.js 20+\n- pnpm\n- Redis\n\n### Asennus\n\n```bash\npnpm install\npnpm exec playwright install chromium\ncp .env.example .env   # täytä ympäristömuuttujat\npnpm db:push\n```\n\n### Ympäristömuuttujat\n\n```env\nDATABASE_URL=\"file:/opt/a11y/prisma/dev.db\"\nREDIS_URL=\"redis://localhost:6379\"\n\nSMTP_HOST=smtp.esimerkki.fi\nSMTP_PORT=587\nSMTP_USER=user@esimerkki.fi\nSMTP_PASS=salasana\nSMTP_FROM=\"Nimi \u003cuser@esimerkki.fi\u003e\"\n\nSENDER_NAME=WP Saavutettavuus\nSENDER_URL=https://app.wpsaavutettavuus.fi\n\nANTHROPIC_API_KEY=sk-ant-...\nHUNTER_API_KEY=...\nBRAVE_SEARCH_API_KEY=...\n```\n\n---\n\n## Käyttö\n\n### Dashboard (suositeltava)\n\n```bash\n# Terminaali 1 — worker\npnpm worker\n\n# Terminaali 2 — dashboard\npnpm dev\n```\n\nAvaa selaimessa: `http://localhost:3000`\n\n| Välilehti | Kuvaus |\n|---|---|\n| **Leadit** | Kaikki liidit, pisteet, yritystiedot, lähde, sähköpostin lisäys/muokkaus, manuaalinen lähetys |\n| **Uusi ajo** | Valitse lähde, toimialasuodatus, käynnistä live-lokilla |\n| **Seuranta** | HTML-muutosseuranta, automaattinen uudelleenskannaus |\n| **⚖️ Kanteet** | Oikeustapaukset FI + NL, AI-analyysi, prioriteetti, yhteydenottokulma, status-seuranta |\n\n### Komentorivi\n\n```bash\npnpm scan https://esimerkki.fi          # yksittäinen skannaus\npnpm scan https://esimerkki.fi --email  # skannaus + sähköposti\n\n# Oikeuskanteet (FI + NL)\npnpm kanteet              # hae molemmat maat + luo AI-tiketit\npnpm kanteet --fi         # vain Suomi (Finlex)\npnpm kanteet --nl         # vain Hollanti (Rechtspraak)\npnpm kanteet --sisalto    # hae myös tapausten koko teksti (parempi analyysi)\n```\n\n---\n\n## Arkkitehtuuri\n\n```\nsrc/\n  dashboard.ts    — Express-palvelin, dashboard-UI, API, /r/:token, /opt-out/:token\n  worker.ts       — BullMQ-worker: skannaus, rikastus, AI-yhteenveto, lähetys\n  queue.ts        — Redis/BullMQ-jono ja ScanJobData-tyyppi\n  scanner.ts      — axe-core + Playwright -skannaus\n  prefilter.ts    — nopea esitarkistus + suurten toimijoiden blocklist\n  enrichment.ts   — sähköpostin etsintä (Hunter → WP REST API → scrape)\n  ai-summary.ts   — Claude Haiku -yhteenveto suomeksi\n  mailer.ts       — HTML-sähköpostipohja (MD→HTML, opt-out-linkki)\n  ytj.ts          — PRH open data (Y-tunnus, TOL)\n  kauppalehti.ts  — liikevaihto ja henkilöstö\n  monitor.ts      — HTML-muutosseuranta\n  pdf.ts          — PDF-raportti (sisäinen käyttö)\n  discovery/\n    index.ts        — orchestraattori, lähdeseuranta\n    duckduckgo.ts   — WordPress-sivustojen haku\n    tranco.ts       — Tranco .fi -domainlista\n    yritykset.ts    — yritykset.fi -hakemistoscrape\n    finlex.ts       — Finlex-skräpperi (FI oikeustapaukset)\n    rechtspraak.ts  — Rechtspraak.nl API (NL oikeustapaukset)\n  court-ticket-agent.ts — Claude analysoi kanteet → tiketti DB:hen\n  kanteet.ts        — runner: FI + NL haku + analyysi + tallennus\n```\n\n### Skannauksen kulku\n\n1. **Pre-filter** — onko sivu elossa, kieli fi, löytyykö CTA, blocklist\n2. **Skannaus** — axe-core / WCAG 2.2 AA Playwrightilla\n3. **Sähköpostin haku** — Hunter → WP REST API → scrape\n4. **YTJ + Kauppalehti** — yritystiedot ja taloustiedot\n5. **Tallennus** — Prisma/SQLite (Domain, Scan, Lead)\n6. **AI-yhteenveto** — Claude Haiku, max 3 kohtaa suomeksi\n7. **Sähköpostilähetys** — linkki `/r/:token` -raporttisivulle\n\n---\n\n## Toimialasuodatus (YTJ)\n\n| TOL | Toimiala |\n|---|---|\n| 47 | Vähittäiskauppa |\n| 55 | Majoitustoiminta |\n| 56 | Ravitsemistoiminta |\n| 68 | Kiinteistöalan toiminta |\n| 85 | Koulutus |\n| 86 | Terveyspalvelut |\n| 88 | Sosiaalihuolto |\n| 90 | Taiteet ja viihde |\n| 96 | Muut henkilökohtaiset palvelut |\n\n---\n\n## Deploy (palvelimelle)\n\nLokaalisti:\n```bash\ncd /path/to/a11y-lead-engine\ntar -czf a11y.tar.gz --exclude=node_modules --exclude=.git --exclude=reports src prisma package.json pnpm-lock.yaml \u0026\u0026 scp a11y.tar.gz a11y@\u003cIP\u003e:/opt/a11y/app/\n```\n\nPalvelimella:\n```bash\ncd /opt/a11y/app \u0026\u0026 tar -xzf a11y.tar.gz \u0026\u0026 chown -R a11y:a11y prisma/ \u0026\u0026 pnpm install \u0026\u0026 pnpm db:push \u0026\u0026 pm2 restart all --update-env\n```\n\n\u003e **Huom:** Jos `pnpm db:push` kysyy resetoinnista, vastaa N ja lisää puuttuvat kolumnit manuaalisesti `sqlite3`-komennolla.\n\n---\n\n## Julkiset reitit\n\n- `/r/:token` — asiakkaalle lähetettävä raporttisivu (ei vaadi kirjautumista)\n- `/opt-out/:token` — GDPR-poistumisilmoitus\n\n---\n\n## Tietoturva\n\n\u003e **Redis-porttia (6379) ei saa altistaa internettiin.** Vanha palvelin kompromissoitiin juuri tästä syystä: Redis oli auki ilman salasanaa.\n\n### Pakolliset toimenpiteet ennen deployta\n\n1. **Generoi Redis-salasana:** `openssl rand -hex 32` → `REDIS_PASSWORD` .env:ään\n2. **Aseta dashboard-tunnukset:** `DASH_USER` ja vahva `DASH_PASS` .env:ään\n3. **Käytä ei-root-käyttäjää:** palvelimella `a11y`-käyttäjä, ei `root`\n4. **Redis kuuntelee vain localhostia:** `docker-compose.yml` on konfiguroitu `127.0.0.1:6379:6379`\n5. **Dashboard kuuntelee vain localhostia:** `app.listen(PORT, '127.0.0.1')` — käytä SSH-tunnelia tai reverse-proxyä\n\n### Tarkistuskomennot palvelimella\n\n```bash\nss -tlnp | grep -E '6379|3030'   # molemmat pitää olla 127.0.0.1\ncurl -i http://localhost:3030/api/stats           # → 401\ncurl -i -u admin:salasana http://localhost:3030/api/stats  # → 200\n```\n\n## Lisenssi\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikko-lab%2Fa11y-lead-engine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmikko-lab%2Fa11y-lead-engine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikko-lab%2Fa11y-lead-engine/lists"}