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,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
Where teams host their work — A focused project tracker for small teams, built for hackathon PS 09.
Hostlink sits between scattered chat threads and heavyweight tools like Jira, giving teams enough structure to stay aligned without the complexity of enterprise project management software.查看完整 README ↗Where teams host their work — A focused project tracker for small teams, built for hackathon PS 09.
Hostlink sits between scattered chat threads and heavyweight tools like Jira, giving teams enough structure to stay aligned without the complexity of enterprise project management software.
Small teams need clarity on who's doing what, when things are due, and what's ready to ship — but most tools either bury you in features you'll never use or leave you stitching updates together from Slack threads. Hostlink gives teams a shared workspace that's light enough to use daily and clear enough to trust.
Implemented:
hostlink/
├── app/ # Next.js App Router pages and API routes
│ ├── (app)/ # Main app layout group
│ │ ├── [section]/ # Dynamic routes for /my-tasks, /analytics, /team, /settings
│ │ └── projects/ # Project routes
│ │ ├── [id]/ # Project detail with [[...view]] catch-all for /board, /list, /analytics
│ │ └── page.tsx # Projects home
│ ├── api/ # API Route Handlers
│ │ ├── users/ # GET /api/users
│ │ ├── projects/ # CRUD for projects
│ │ │ └── [id]/ # Project detail, tasks, analytics
│ │ ├── tasks/ # Task CRUD, move, comments
│ │ ├── comments/ # Comment deletion
│ │ └── my-tasks/ # Personal task list
│ ├── login/ # Demo login page
│ ├── page.tsx # Marketing landing page
│ └── layout.tsx # Root layout
├── components/ # React components
│ ├── analytics/ # Chart components (burndown, completion ring, workload)
│ ├── board/ # Kanban board, columns, task cards, quick-add
│ ├── landing/ # Marketing page, login page, product preview
│ ├── layout/ # App shell, sidebar, topbar, breadcrumbs, search
│ ├── list/ # Task table, status dropdown, filters
│ ├── projects/ # Project list, cards, new project modal
│ ├── task/ # Task drawer, modal, fields, activity feed, toolbar
│ ├── ui/ # Base UI components (button, dialog, badge, etc.)
│ └── workspace/ # My Tasks, Team, Settings, Workspace Analytics
├── lib/ # Utilities and business logic
│ ├── api.ts # API client functions (calls backend routes)
│ ├── db.ts # Prisma client singleton
│ ├── hooks.ts # React hooks (useSWR wrappers)
│ ├── seed.ts # Database seed script
│ ├── store.ts # Zustand state (UI state only, domain data from API)
│ ├── types.ts # TypeScript types
│ ├── utils.ts # Utility functions (transitions, analytics, sorting)
│ └── *.test.ts # Test files
├── prisma/
│ └── schema.prisma # Database schema
├── public/ # Static assets
├── .env # Environment variables
├── package.json # Dependencies and scripts
└── README.md # This file
The database uses Prisma ORM with the following tables:
id (String, primary key)name (String)email (String, unique)role (String) — e.g. "Team Lead", "Developer", "Designer"color (String) — for avatar themingcreatedAt (DateTime)id (String, primary key)name (String)description (String, optional)color (String) — for project card/iconcreatedAt (DateTime)updatedAt (DateTime, optional)members (ProjectMember[]), tasks (Task[]), taskEvents (TaskEvent[])id (String, primary key, auto-generated UUID)projectId (String, foreign key)userId (String, foreign key)(projectId, userId)id (String, primary key)key (String, unique) — e.g. "HL-12"projectId (String, foreign key)title (String)description (String, optional)assigneeId (String, foreign key → User)priority (String) — "urgent" | "high" | "normal"status (String) — "backlog" | "in_progress" | "review" | "done"dueDate (String) — ISO date format (yyyy-MM-dd)createdAt (DateTime)movedAt (DateTime) — last status changecompletedAt (DateTime, optional) — set when status becomes "done"comments (Comment[]), events (TaskEvent[])(projectId, status), assigneeIdid (String, primary key)taskId (String, foreign key)authorId (String, foreign key → User)body (String)createdAt (DateTime)taskIdid (String, primary key)taskId (String, foreign key)projectId (String, foreign key)userId (String, foreign key → User)fromStatus (String, optional) — null for task creationtoStatus (String)createdAt (DateTime)(projectId, createdAt), taskIdCascading Deletes: Deleting a project cascades to its tasks, comments, project members, and task events. Deleting a task cascades to its comments and events.
All routes return JSON. Errors return { error: string } with appropriate HTTP status codes.
| Method | Path | Purpose |
|---|---|---|
| GET | /api/users | List all users |
| GET | /api/projects | List projects with computed stats (task count, completion %, overdue count) |
| POST | /api/projects | Create a new project |
| GET | /api/projects/:id | Get project details |
| PATCH | /api/projects/:id | Update project (name, description, color, members) |
| DELETE | /api/projects/:id | Delete project (cascades) |
| GET | /api/projects/:id/tasks | List tasks for a project (supports ?q=, ?assignee=, ?priority=, ?status= filters) |
| POST | /api/projects/:id/tasks | Create a task in a project |
| GET | /api/projects/:id/analytics | Per-project analytics (completion %, burndown, workload, overdue) |
| GET | /api/tasks/:id | Get task details with comments and events |
| PATCH | /api/tasks/:id | Update task fields (title, description, assignee, priority, due date) |
| DELETE | /api/tasks/:id | Delete task (cascades) |
| POST | /api/tasks/:id/move | Move task to new status — validates transition, updates status, stamps timestamps, creates TaskEvent. Returns 422 with { error, allowed: [...] } on invalid transitions. |
| GET | /api/tasks/:id/comments | List comments for a task |
| POST | /api/tasks/:id/comments | Add a comment to a task |
| DELETE | /api/comments/:id | Delete a comment |
| GET | /api/my-tasks?userId= | Tasks assigned to a user across all projects |
Enforced server-side in /api/tasks/:id/move:
| From Status | Allowed To |
|---|---|
| Backlog | In Progress |
| In Progress | Backlog, Review |
| Review | In Progress, Done |
| Done | Review (reopen) |
Invalid transitions return HTTP 422 with { error: string, allowed: Status[] }.
# Clone the repository
git clone <your-repo-url>
cd hostlink
# Install dependencies
npm install
# or
pnpm install
# Set up environment variables
# Create a .env file in the project root (see Environment Variables section below)
# Initialize the database
npx prisma db push
# Seed the database with demo data
npx tsx lib/seed.ts
# Run the development server
npm run dev
The app will be available at http://localhost:3000.
Create a .env file in the project root with the following variables:
| Variable | Purpose | Example Value |
|---|---|---|
DATABASE_URL | Prisma database connection string | file:./dev.db (SQLite) or postgresql://... (Postgres) |
For SQLite (default, local development):
DATABASE_URL="file:./dev.db"
For Postgres (production):
DATABASE_URL="postgresql://user:password@host:5432/hostlink?schema=public"
Note: The schema in prisma/schema.prisma supports both SQLite (provider = "sqlite") and PostgreSQL. For production deployment, change the provider to "postgresql" and update DATABASE_URL.
| Script | Command | Description |
|---|---|---|
dev | npm run dev | Start the Next.js development server (Turbopack) on port 3000 |
build | npm run build | Build the production bundle |
start | npm run start | Start the production server |
test | npm run test | Run the test suite (via tsx --test) |
typecheck | npm run typecheck | Run TypeScript type checking without emitting files |
| Prisma | ||
prisma db push | npx prisma db push | Push the Prisma schema to the database (creates/updates tables) |
prisma generate | npx prisma generate | Generate the Prisma Client |
prisma studio | npx prisma studio | Open Prisma Studio to browse and edit database data |
| Seed | ||
seed | npx tsx lib/seed.ts | Populate the database with demo users, projects, and tasks |
The project includes test files (lib/*.test.ts) that were written for an earlier in-memory implementation. These tests are currently not functional and need to be rewritten to work with the real Prisma database and API routes.
Test coverage areas (to be updated):
To run tests (once updated):
npm run test
Recommended approach for test updates:
test.db via DATABASE_URL)prisma db push before tests to initialize the schemabeforeEach hooksjest-mock-extended or vitestHostlink is optimized for deployment on Vercel (Next.js's native platform):
Push your code to GitHub/GitLab/Bitbucket
Import the project on Vercel
Set environment variables in the Vercel dashboard:
DATABASE_URL="file:./dev.db"DATABASE_URL to the connection stringUpdate prisma/schema.prisma for Postgres:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
Add a build command (if not auto-detected):
prisma generate && next buildnpm install (or pnpm install if using pnpm)Deploy
After deploying, seed the database:
Option 1: Via Vercel CLI
vercel env pull .env.local
npx tsx lib/seed.ts
Option 2: Create a one-time seed API route
// app/api/seed/route.ts
import { exec } from 'child_process'
import { promisify } from 'util'
const execAsync = promisify(exec)
export async function POST(request: Request) {
// Add authentication/secret check here
const { secret } = await request.json()
if (secret !== process.env.SEED_SECRET) {
return Response.json({ error: 'Unauthorized' }, { status: 401 })
}
await execAsync('npx tsx lib/seed.ts')
return Response.json({ success: true })
}
Then call POST /api/seed once with your secret, then delete the route.
Hostlink includes a "Continue as demo user" flow — no authentication required, perfect for hackathon demonstrations or trying the app.
The seeded database includes three users you can switch between:
u1u2u3All demo users are members of both projects and own various tasks.
/projects)Built for Hackathon PS 09 | © 2026 Hostlink | Demo preview — No persistent storage beyond the database