mirror of
https://github.com/saltbo/zpan.git
synced 2026-08-30 17:50:07 +08:00
00f48cf355
* feat(avatars): host avatars + team logos on Cloud via SDK 2.4.0; remove public-bucket mode Host user avatars and org logos on the ZPan Cloud avatar service (zpan-cloud-sdk ^2.4.0) instead of a public S3/R2 bucket, then remove the now-dead storages.mode / public-bucket concept entirely (#456 parts 2-3). - image-upload gateway: upload/delete via SDK uploadAvatar/deleteAvatar against a bound Cloud client; validate mime (AVATAR_CONTENT_TYPES) + size (MAX_AVATAR_BYTES) before the call; map cloud error codes to 400/403/413/500; unbound instance returns 503 cloud_required (delete is a best-effort no-op). - licensing-cloud: createAvatarUploadClient builds the client with a plain-object bearer header so both the image content-type and Authorization survive hono's per-request header merge (a Headers instance would be dropped). - drop storages.mode (migration via drizzle-kit), StorageRepo.select() no longer takes a mode, remove StorageMode / Storage.mode / mode schema+audit+UI+i18n and the PUBLIC_IMAGES bucket + PUBLIC_IMAGES_URL wiring. Agent-Profile: https://agent-kanban.dev/agents/f759c704c282d88a * ci(deploy): drop dead PUBLIC_IMAGES R2 provisioning from CF deploy The Cloud avatar migration removed the PUBLIC_IMAGES binding from wrangler.toml, so the deploy workflow's R2 public-images steps are dead and must go too — otherwise every CF deploy keeps re-provisioning a public-read zpan-public-images bucket (the footgun #456 eliminates) and sets an unused PUBLIC_IMAGES_URL secret. Removes the bucket-create, managed-public-URL, and secret steps (steps.r2 was only consumed by the secret step). Also drops a stale storage-modes line from the v2.0 roadmap. Agent-Profile: https://agent-kanban.dev/agents/f759c704c282d88a --------- Co-authored-by: Alex Chen <alex-chen@mails.agent-kanban.dev>
74 lines
2.7 KiB
TypeScript
74 lines
2.7 KiB
TypeScript
export const UserRole = {
|
|
ADMIN: 'admin',
|
|
MEMBER: 'member',
|
|
} as const
|
|
|
|
export type UserRole = (typeof UserRole)[keyof typeof UserRole]
|
|
|
|
export const DirType = {
|
|
FILE: 0,
|
|
USER_FOLDER: 1,
|
|
SYSTEM_FOLDER: 2,
|
|
} as const
|
|
|
|
export type DirType = (typeof DirType)[keyof typeof DirType]
|
|
|
|
export const StorageStatus = {
|
|
ACTIVE: 'active',
|
|
INACTIVE: 'inactive',
|
|
} as const
|
|
|
|
export type StorageStatus = (typeof StorageStatus)[keyof typeof StorageStatus]
|
|
|
|
// Soft delete is tracked by the `trashedAt` timestamp, not a status value:
|
|
// live = active & trashedAt IS NULL, trash = active & trashedAt IS NOT NULL.
|
|
export const ObjectStatus = {
|
|
DRAFT: 'draft',
|
|
ACTIVE: 'active',
|
|
} as const
|
|
|
|
export type ObjectStatus = (typeof ObjectStatus)[keyof typeof ObjectStatus]
|
|
|
|
export const SignupMode = {
|
|
OPEN: 'open',
|
|
INVITE_ONLY: 'invite_only',
|
|
CLOSED: 'closed',
|
|
} as const
|
|
|
|
export type SignupMode = (typeof SignupMode)[keyof typeof SignupMode]
|
|
|
|
export const ZPAN_CLOUD_URL_DEFAULT = 'https://cloud.zpan.space'
|
|
export const ZPAN_GITHUB_URL = 'https://github.com/saltbo/zpan'
|
|
// The About page renders this hand-maintained, product-facing changelog in a
|
|
// side drawer; raw.githubusercontent.com serves the file with CORS.
|
|
export const ZPAN_CHANGELOG_RAW_URL = 'https://raw.githubusercontent.com/saltbo/zpan/main/CHANGELOG.md'
|
|
// The latest-version indicator comes from the newest published GitHub Release
|
|
// (tag_name), not the changelog file — releases are the source of truth for
|
|
// "what's the latest shipped version".
|
|
export const ZPAN_RELEASES_LATEST_API_URL = 'https://api.github.com/repos/saltbo/zpan/releases/latest'
|
|
// Build a link to a specific commit on GitHub.
|
|
export const githubCommitUrl = (sha: string) => `${ZPAN_GITHUB_URL}/commit/${sha}`
|
|
export const DEFAULT_SITE_NAME = 'ZPan'
|
|
export const DEFAULT_SITE_DESCRIPTION = ''
|
|
export const DEFAULT_ORG_QUOTA = 10 * 1024 * 1024
|
|
export const DEFAULT_ORG_TRAFFIC_QUOTA = 0
|
|
|
|
// Free plan allows up to this many organizations per user (including personal workspace).
|
|
// The 3rd organization requires the teams_unlimited feature.
|
|
export const FREE_TEAM_LIMIT = 2
|
|
|
|
// Free plan allows up to this many extra team workspaces beyond the personal workspace.
|
|
export const FREE_EXTRA_TEAM_LIMIT = 1
|
|
|
|
// Free plan allows up to this many storage backends per instance.
|
|
// The 4th storage requires the storages_unlimited feature.
|
|
export const FREE_STORAGE_LIMIT = 3
|
|
|
|
// Free plan allows up to this many social login / OIDC providers per instance.
|
|
// The 2nd provider requires the social_login_unlimited feature.
|
|
export const FREE_SOCIAL_LOGIN_LIMIT = 1
|
|
|
|
// Free plan allows up to this many downloaders per instance.
|
|
// The 2nd downloader requires the downloaders_unlimited feature.
|
|
export const FREE_DOWNLOADER_LIMIT = 1
|