尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
Le barriere del web, segnalate da chi le incontra. A public directory of reports about inaccessible websites, apps and digital documents, moderated before publication.
The design comes from Barriere Digitali.html (a bundled design export).檢視完整 README ↗Le barriere del web, segnalate da chi le incontra. A public directory of reports about inaccessible websites, apps and digital documents, moderated before publication.
The design comes from Barriere Digitali.html (a bundled design export).
typedRoutes), React 19, TypeScript 6src/app/globals.css@prisma/adapter-pg); the client is generated into src/generated/prismanext + full jsx-a11y + prettier)Requirements: Node 22.22+ (nvm use), Docker.
npm install
cp .env.example .env
npm run db:up # Postgres on localhost:5433
npm run db:migrate # applies the migrations
npm run db:seed # example data: real public services (local only)
npm run dev
The seed (prisma/seed.ts) refuses to run if DATABASE_URL does not point to a local database, or if NODE_ENV=production or VERCEL is set.
| Command | Description |
|---|---|
npm run dev | Development server |
npm run build | prisma generate + production build |
npm run lint | ESLint (includes the accessibility rules) |
npm run check-types | Route type generation + tsc |
npm run format | Prettier |
npm test | Unit and component tests (Vitest + axe-core) |
npm run test:e2e | Playwright: axe WCAG 2.2 AA, keyboard, focus, reflow |
npm run db:studio | Prisma Studio (moderation) |
npm run db:deploy | Applies the migrations in production |
Reports arrive with status = PENDING and no linked service. To publish one, open npm run db:studio (pointed at the right database) and:
Service if it does not exist yet. You need slug, name, type, and nameNormalized, which is the name in lowercase without https:// or www..Report, set serviceId, status = PUBLISHED and publishedAt (the date shown to the public). Remove any personal data from description first.Counts and dates in the list are computed from published reports, so nothing else needs updating. Public pages cache database reads for about a minute (cacheLife("minutes") in src/lib/services.ts), so a change made in Studio appears within that time. The sitemap refreshes every hour.
Abuse protection: each IP can send at most 5 reports in 10 minutes and 20 per day, and an identical report sent again within 10 minutes is not saved twice (src/lib/rate-limit.ts). The IP is never stored: only a daily HMAC (ip_hash), keyed with IP_HASH_SECRET. Without that variable in production, the per-IP limit is off.
To give the site a base of real reports before the public ones arrive, the editorial team audits well-known Italian websites (scripts/audit/targets.ts).
npm run audit:scan # or: npm run audit:scan -- inps.it tim.it
# review audit-results/<date>.md, then:
npm run audit:import -- audit-results/<date>.json # local DB, as PENDING
npm run audit:import -- audit-results/<date>.json --publish # local DB, published
DATABASE_URL=… npm run audit:import -- audit-results/<date>.json --publish --remote # production
scan checks the home page and up to two key pages (contacts, services, accessibility, help) with axe-core WCAG 2.2 AA and a reflow check at 320 px.scripts/audit/rules.ts become reports, with at most 6 per service. Any other finding is dropped, so no generic or unverified text is published.reports.evidence: page URL, date, rule, WCAG criteria and affected elements. reports.source is EDITORIAL. Neither is shown on the site.aria-current in the menus, focus moved to the heading after every navigation, and back to the service you came from when returning to the list (same search, sort and page).export const instant = false): the server sends complete HTML, so search, sorting, pagination and the form work without JavaScript, with no layout shift.
useActionState state to the HTML in that case.aria-describedby, and a page title prefixed with "Errori nel modulo".npm test: Vitest + Testing Library + axe-core (normalisation, pagination, validation, components).npm run test:e2e: Playwright on desktop (1440px) and mobile (390px), against the local seed (npm run db:seed). Expected values are derived from prisma/seed-data.ts.
e2e-*) are deleted at the end.fra1 (Frankfurt), next to the database.barrieredigitali (db.t4g.micro, eu-central-1, AWS account 179743357810). Storage is encrypted, backups are kept for 7 days and deletion protection is on.
bd_app, owner of the barrieredigitali database only. TLS is required: the app verifies the certificate against the RDS CA (src/lib/db.ts); any non-local host must use verified TLS; DATABASE_URL carries sslmode=require for the Prisma migrations.bd_admin and bd_app are in AWS Secrets Manager (barrieredigitali/db).barrieredigitali-db), because Vercel has no fixed IPs.DATABASE_URL (user bd_app), IP_HASH_SECRET (random, for the submission limit) and SITE_URL (https://barrieredigitali.org).vercel-build runs prisma migrate deploy only on production builds; previews do not touch the database. Never run the seed in production.DATABASE_URL points to the Postgres in Docker.