Jasper Van 2c8e2cc837 feat: v2.3.0 T1 — 站内信系统 (in-app notifications) (#307)
* feat: add in-app notification system (站内信) — schema, service, API, Bell UI

- Add `notifications` table to DB schema with userId/type/title/body/refType/refId/metadata/readAt/createdAt fields; two indexes for list & unread queries
- Migration `0010_notifications.sql` created manually (drizzle-kit requires TTY)
- Service layer: createNotification, listNotifications (paginated + unreadOnly filter), markAsRead (idempotent, owner-only), markAllAsRead, unreadCount
- REST API at `/api/notifications`: list + unreadCount, GET unread-count, POST :id/read (204), POST read-all
- Shared `Notification` type, `listNotificationsQuerySchema`, RPC client export
- NotificationBell (badge, 30s polling), NotificationDropdown, NotificationItem components injected into AppSidebar footer
- Bell badge capped at "9+"; unread items bold; click marks read + navigates via refType/refId
- i18n: en + zh translations for all notification keys
- 26 Node integration tests + 5 CF smoke tests; all 1884 + 26 tests pass

Agent-Profile: https://agent-kanban.dev/agents/a6bb038c4226a87f

* test: add notification API wrapper tests and component logic tests; fix dead condition

- Add tests for listNotifications, getUnreadCount, markNotificationRead, markAllNotificationsRead in api.test.ts
- Add notification-bell.test.ts: badge label logic (0/5/"9+" cap) and polling interval
- Add notification-dropdown.test.ts: mark-all-read visibility, empty state, query key
- Add notification-item.test.ts: resolveHref (share token nav, malformed JSON), diffMinutes, isUnread, title style
- Fix dead condition in markNotificationRead: simplify `!res.ok && res.status !== 204` → `!res.ok`

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* ci: trigger CI check run for test coverage fixes

---------

Co-authored-by: Bob <aibob@mails.agent-kanban.dev>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 01:23:54 -04:00
2026-04-14 23:44:12 -04:00
2020-10-13 01:50:40 +08:00

ZPan

The open-source, S3-native file hosting platform.

CI codecov Release GitHub Release Docker Image License

Image bed, file sharing, and backup — powered by S3, deployed anywhere.

What is ZPan?

ZPan is a lightweight file hosting platform built on top of S3-compatible storage. Files upload directly from the client to S3, bypassing server bandwidth entirely.

Three scenarios, one platform:

  • Image Bed — Upload via PicGo / ShareX / API, get a URL instantly
  • File Sharing — Upload files, generate share links, distribute to anyone
  • File Backup — CLI agent syncs local directories to S3/R2

Deploy

One-click deploy with zero server management. Free tier covers personal use.

Deploy to Cloudflare

Docker

docker compose up -d

Documentation

Why ZPan?

  • Zero bandwidth bottleneck — files transfer directly between client and S3
  • Zero ops option — deploy to Cloudflare Workers for free, no server needed
  • Self-host friendly — Docker deployment with any S3-compatible storage
  • Tool ecosystem — works with PicGo, ShareX, Flameshot out of the box
  • Open source — free forever for self-hosted users

v1

Looking for ZPan v1 (Go version)? See the v1 branch.

Contributing

See CONTRIBUTING.md for details.

Thank you to all the people who contributed to ZPan!

License

ZPan is under the GPL 3.0 license. See the LICENSE file for details.

S
Description
A self-hosted cloud disk base on the cloud storage./ 一个基于云存储的网盘系统,用于自建私人网盘或企业网盘。
Readme AGPL-3.0 71 MiB
Languages
TypeScript 92.7%
Go 6.5%
JavaScript 0.5%
CSS 0.1%