TreeMap
A free, open-source disk-space visualizer. Squarified treemap, duplicate hunting, disk-full forecasting, and cleanup that only ever moves files to the Trash.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Cover your network. A private networking tracker and call calendar for students recruiting for internships.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Coverage is a list for your recruiting season: every banker, alum, and recruiter you’re talking to, where each conversation stands, and the calls on your calendar.
Cover your network. A private networking tracker for college students recruiting for internships: a spreadsheet-style contact grid plus a weekly call calendar.
Live demo: https://coverage-green.vercel.app · sign up free, then click Try with example data.
| Import from LinkedIn, with a review step | Book calls on a weekly calendar |
|---|---|
Connections.csv from LinkedIn's data export (or any tracker CSV), or paste profile URLs. Every
import goes through an editable review table that skips duplicates.All free tiers; no paid APIs.
| Layer | Choice |
|---|---|
| Framework | Next.js 16 (App Router, Cache Components) · React 19 · TypeScript |
| Styling | Tailwind CSS v4 with design tokens · IBM Plex Sans/Mono + Source Serif 4 |
| Auth + database | Supabase: Auth (email, Google OAuth) and Postgres with Row Level Security |
| Calendar | FullCalendar v6 (MIT core: timeGrid + interaction) |
| PDF parsing | pdf.js (pdfjs-dist), lazy-loaded, runs in the browser |
| Testing | Vitest (unit + RLS isolation) · Playwright + axe-core (end-to-end + accessibility) |
| CI / hosting | GitHub Actions · Vercel Hobby |
flowchart LR
subgraph Browser
UI["React UI<br/>Contacts grid · Calendar · Import"]
PDF["pdf.js<br/>(profile PDFs never leave the browser)"]
SBC["Supabase JS client<br/>(publishable key only)"]
UI --> PDF
UI --> SBC
end
subgraph Vercel["Vercel (Next.js)"]
PX["proxy.ts<br/>refresh session cookie,<br/>guard /contacts /calls /account"]
RH["Route handlers<br/>/auth/callback · /auth/confirm · /auth/signout"]
RSC["Server Components<br/>(read the signed-in user)"]
end
subgraph Supabase
AUTH["Auth<br/>email + Google"]
PG[("Postgres<br/>profiles · contacts · calls<br/>Row Level Security")]
end
Google["Google OAuth"]
UI -- page requests --> PX
PX --> RSC
SBC -- "queries with the user's JWT" --> PG
SBC --> AUTH
RH --> AUTH
AUTH <--> Google
RSC --> PG
Most reads and writes go directly from the browser to Postgres with the user's session token. There is no custom API layer to secure: the database decides what each request may see.
| Table | Columns |
|---|---|
profiles | id → auth.users, full_name, created_at (created by a trigger on sign-up) |
contacts | id, user_id, company, name, title, stage (contacted | call_scheduled | called), follow_up_date, notes, linkedin_url, is_example, created_at, updated_at |
calls | id, user_id, contact_id → contacts, starts_at, duration_minutes (default 30) |
contact_notes | contact_id → contacts (one per contact), user_id, doc (JSON notes document), updated_at |
contacts also has an optional email. contacts.notes holds a plain-text copy of the notes document so the grid
preview, search, and CSV export never need to load every document.
Every foreign key to auth.users is on delete cascade, so deleting an account removes all of its data. SQL lives in
supabase/migrations.
select / insert / update / delete policies require
auth.uid() = user_id (or = id for profiles). Logged-out requests match no policy. The calls insert/update
policies (and the same policies on contact_notes) also check that the linked contact belongs to the same user, so
you can't attach a call or notes to someone else's contact. (0002_rls.sql)security definer function that can only delete the caller's own
auth.users row. (0003_functions.sql)tests/rls/isolation.test.ts signs in as two ordinary users and
checks that user B can't read, update, delete, or insert into user A's contacts, calls, notes, or profile, and that
logged-out requests see nothing.@supabase/ssr keeps the session in HTTP cookies; proxy.ts validates the JWT (getClaims) on each
request. Server code never trusts an unverified session.?next= values pass through safeNextPath(), which rejects absolute and protocol-relative URLs
(no open redirects). Log out is POST-only.=, +, -, or @ so a malicious name can't run a spreadsheet
formula..env.local is git-ignored; documents every variable.You need Node.js 24+ and a free Supabase project.
git clone https://github.com/tfinn18/coverage.git
cd coverage
npm install
cp .env.example .env.local # add your Supabase URL and publishable key
npm run dev # http://localhost:3000
supabase/migrations/ in order (0001 → 0005).http://localhost:3000/** to Redirect URLs.https://<project-ref>.supabase.co/auth/v1/callback as an authorized redirect URI, and paste the client ID and
secret into Supabase → Authentication → Sign In / Providers → Google.| Command | What it checks |
|---|---|
npm run lint · npm run typecheck | ESLint and TypeScript |
npm test | 60 unit tests: CSV and PDF parsers (with fixture files), import mapping and duplicate detection, sort/filter, follow-up flags, scheduling helpers, Google Calendar links, the notes document (including converting the old layout), list editing, Gmail and mailto links, safe redirects |
npm run test:rls | 8 checks that one user can't touch another's rows, including notes (needs two test accounts in .env.local) |
npm run test:e2e | Playwright: sign in, add a contact, reload, see it on the calendar, delete it; write and reopen notes (Enter/Backspace lists, Copy, Open in Gmail, Escape), notes from the old layout open in the new one; the notes sheet at phone width; plus axe WCAG 2.1 AA scans of 8 pages and the open notes panel in light and dark mode. E2E_BASE_URL=https://coverage-green.vercel.app runs it against production |
GitHub Actions runs lint, typecheck, unit tests, and a production build on every push. The RLS and end-to-end suites need real credentials, so they run locally.
src/
app/ routes: landing, privacy, (auth) pages, (app) pages, auth route handlers
components/ ui primitives, contacts grid, import dialog, calls calendar
lib/ framework-free logic (unit-tested): contacts, csv, pdf, linkedin, import, calls
lib/supabase/ browser client, server client, session proxy
proxy.ts route guard (Next.js 16's name for middleware)
supabase/migrations/ schema, RLS policies, functions
tests/ unit tests, fixtures, RLS isolation test
e2e/ Playwright end-to-end and accessibility tests
A starting point for interviews and resume bullets. Edit it into your own words.
security definer SQL function instead, so no secret key exists in the codebase or on Vercel.CLAUDE.md records the
conventions it followed.Resume bullets (examples):
Supabase's free plan only allows editing the auth email templates once you configure a custom SMTP server, so Coverage uses Supabase's default confirmation and password-reset emails.
Those default emails use the PKCE flow: the link carries a one-time code that can only be exchanged
for a session in the same browser that requested the email (a secret "code verifier" is stored there).
What that means in practice:
How to remove the limitation: add custom SMTP in Supabase (Authentication → Emails → SMTP Settings;
a free tier from a provider like Resend or Brevo works), then change the two templates so their links
use a token_hash, which /auth/confirm already supports on any device:
<!-- Confirm signup -->
<a href="{{ .RedirectTo }}?token_hash={{ .TokenHash }}&type=email">Confirm your email</a>
<!-- Reset password -->
<a href="{{ .RedirectTo }}&token_hash={{ .TokenHash }}&type=recovery">Reset your password</a>
(The reset link uses & because its redirect URL already contains ?next=/reset-password.)
.env.example