由 rio 出售

Shelf is an open-source asset management platform for teams to track physical equipment, tools, and inventory via QR codes, bookings, custody tracking, and role-based access across multiple workspaces.
Shelf is a full-stack React Router 7 (React 19) web application for tracking physical assets across teams and locations. It provides QR-based asset tagging, booking/reservation workflows, custody tracking, audit trails, CSV import/export, and multi-workspace support. The typical buyer is a team embedding or self-hosting a complete asset management system, or extracting specific UI components (notes, asset images, bulk-update flows) into an existing project.
app/ - Core React Router application: routes, components, modules, hooks, utils, stylesapp/atoms/ - Jotai atom definitions for global UI state (bulk updates, notifications, QR scanner, workspace switching)app/components/ - All UI components organized by domain (assets, bookings, audit, kits, locations, forms, layout, etc.)app/config/ - Application-wide configuration constantsapp/database/ - Prisma client setup and database access helpersapp/emails/ - Email templates and sending utilitiesapp/hooks/ - Shared custom React hooksapp/integrations/ - Third-party service integrations (Stripe, Supabase, etc.)app/modules/ - Domain logic modules (assets, bookings, users, permissions, etc.)app/routes/ - React Router file-based route definitionsapp/utils/ - Shared utility functions (form helpers, date, permissions, etc.)desktop-app/ - Companion Electron/desktop shellserver/ - Custom Express/Node server entry pointsso/ - SSO (SAML/OIDC) configuration and middlewarescripts/ - Build, migration, and maintenance scriptspublic/ - Static assets (images, icons, fonts)prisma.config.ts - Prisma schema path and datasource configurationreact-router.config.ts - React Router v7 framework configurationvite.config.ts - Vite build configurationtailwind.config.ts - Tailwind CSS configuration and theme extensiontsconfig.json - TypeScript compiler configurationvitest.config.ts - Unit test configuration启动隔离沙箱并在服务器端直接运行 — 无需本地配置。
此版本的 Tetrees AI Review
This React web app completed archive review with strong static results. Structure, dependency manifests, documentation, functional source, and common risk patterns were checked by the Tetrees verification pipeline; runtime phases are stated separately.
Deterministic AVCP artifact review
管道 avcp-2026-08-04.1 · SHA-256 78e35cbfcec7bde6…
This version-scoped review deterministically inspects the submitted archive for structure, dependencies, documentation, functional source, and common malicious or high-risk signals. Build and test phases are reported as passed only after an isolated sandbox audition. It is not a guarantee of perfect security.
审查日期 2026年8月4日
将此产品直接导入你的 AI IDE、网页构建器或云端 IDE。
将 Tetrees 连接到兼容的 AI IDE,列出你拥有的产品并获取已验证 ZIP,同时不会开放卖家上传权限。
暂无评价。
Sign in to join the discussion
Loading discussion…
npm install react react-dom react-router @react-router/node @react-router/serve
npm install @prisma/client prisma
npm install @supabase/supabase-js @supabase/auth-helpers-remix
npm install jotai
npm install @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-select @radix-ui/react-tooltip @radix-ui/react-popover @radix-ui/react-checkbox
npm install tailwindcss postcss autoprefixer
npm install zod
npm install stripe
npm install pg-boss
npm install nodemailer
npm install papaparse
npm install date-fns
npm install clsx tailwind-merge
npm install lucide-react
npm install @tiptap/react @tiptap/starter-kit
npm install lottie-react
npm install playwright --save-dev
npm install vitest @vitejs/plugin-react --save-dev
No native module linking is required. If deploying via Docker, use docker-entrypoint.sh as the container entry point. Run npx prisma generate after install to generate the Prisma client.
Copy the source/ directory contents into your project root or a dedicated subdirectory (e.g., apps/webapp/).
Install dependencies as shown above, then run:
npx prisma generate
npx prisma migrate deploy
Configure tsconfig.json path aliases — the source uses ~/ mapped to app/:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"~/*": ["./app/*"]
}
}
}
Copy .env.example to .env and populate the required variables:
DATABASE_URL="postgresql://user:password@host:5432/shelf"
SUPABASE_URL="https://your-project.supabase.co"
SUPABASE_ANON_PUBLIC_KEY="your-anon-key"
SUPABASE_SERVICE_ROLE="your-service-role-key"
SESSION_SECRET="a-long-random-string"
STRIPE_SECRET_KEY="sk_..."
STRIPE_WEBHOOK_SIGNATURE="whsec_..."
SMTP_HOST="smtp.example.com"
SMTP_PORT="587"
SMTP_USER="user"
SMTP_PWD="password"
INVITE_TOKEN_SECRET="another-long-random-string"
Start the development server:
npm run dev
For production, build then start:
npm run build
npm start
import { AssetImage } from "~/components/assets/asset-image";
import type { AssetImageProps } from "~/components/assets/asset-image";
Renders a responsive asset image with preview support. Use it anywhere an asset's main image needs to be displayed — asset cards, detail pages, list rows. AssetImageProps extends standard <img> props with asset-specific fields sourced from the loader.
import { ImportUpdateContent } from "~/components/assets/bulk-update";
Self-contained page component for the bulk CSV asset update workflow. Renders collapsible step-by-step instructions, a download prompt for the asset index, and embeds UpdateImportForm which handles upload, diff preview, and apply. Drop it into a route that matches /assets/import-update.
import { Notes } from "~/components/assets/notes";
Displays the full activity/notes panel for a single asset. Reads loader data from ~/routes/_layout+/assets.$assetId.activity, implements optimistic UI via a useFetcher keyed "add-note", and includes export-to-CSV. Use inside the asset activity route layout.
import { AuditNotes } from "~/components/audit/notes";
Equivalent of Notes scoped to audit sessions. Reads from the audits.$auditId.activity loader and keys its fetcher as "add-audit-note". Use inside audit session activity routes.
import { BookingNotes } from "~/components/booking/notes";
Notes panel for booking records. Reads from bookings.$bookingId.activity loader, includes booking-specific action dropdown, and follows the same optimistic-UI pattern. Use inside booking activity route layouts.
Add the activity notes UI to a custom asset detail page that already has a loader providing asset.notes.
// app/routes/my-asset.$assetId.activity.tsx
import type { LoaderFunctionArgs } from "react-router";
import { useLoaderData } from "react-router";
import { Notes } from "~/components/assets/notes";
import { db } from "~/database/db.server";
export async function loader({ params }: LoaderFunctionArgs) {
const asset = await db.asset.findUniqueOrThrow({
where: { id: params.assetId },
include: {
notes: {
include: { user: { select: { firstName: true, lastName: true } } },
orderBy: { createdAt: "desc" },
},
},
});
return { asset };
}
export default function AssetActivity() {
return (
<div className="p-4">
<Notes />
</div>
);
}
Use AssetImage to display a thumbnail with preview on a custom asset listing.
// app/components/my-asset-card.tsx
import { AssetImage } from "~/components/assets/asset-image";
import type { AssetImageProps } from "~/components/assets/asset-image";
interface MyAssetCardProps {
asset: {
id: string;
title: string;
mainImage: string | null;
mainImageExpiration: string | null;
};
}
export function MyAssetCard({ asset }: MyAssetCardProps) {
return (
<div className="rounded-lg border p-3 flex gap-3 items-center">
<AssetImage
asset={asset}
alt={asset.title}
className="h-12 w-12 rounded object-cover"
/>
<span className="font-medium">{asset.title}</span>
</div>
);
}
Wire ImportUpdateContent into a dedicated route for bulk asset updates.
// app/routes/assets.import-update.tsx
import type { ActionFunctionArgs, LoaderFunctionArgs } from "react-router";
import { ImportUpdateContent } from "~/components/assets/bulk-update";
import { requireAuthSession } from "~/modules/auth/session.server";
export async function loader({ request }: LoaderFunctionArgs) {
await requireAuthSession(request);
return {};
}
export async function action({ request }: ActionFunctionArgs) {
// Delegate to the CSV parse/diff/apply handler in app/modules/asset/
return {};
}
export default function ImportUpdatePage() {
return (
<div className="mx-auto max-w-3xl py-8">
<ImportUpdateContent />
</div>
);
}
app/entry.client.tsx - React 19 client hydration entry point via hydrateRoot.app/entry.server.tsx - Server-side rendering handler for React Router's handleRequest.app/root.tsx - Root layout component: sets HTML shell, global providers, error boundary.app/routes.ts - React Router v7 routes() configuration wiring all file-based routes.app/tailwind.css - Tailwind CSS base import; extended by tailwind.config.ts.app/atoms/ - Jotai atoms for cross-component state: bulk selections, notifications, QR scanner, workspace.app/components/ - All domain UI components. Sub-directories mirror features: assets/, booking/, audit/, kits/, location/, forms/, layout/, list/, etc.app/config/ - Static configuration (plan limits, feature flags, route constants).app/database/ - Prisma client singleton and typed query helpers.app/emails/ - React-based email templates rendered server-side for transactional mail.app/hooks/ - Reusable hooks: useUserData, useViewportHeight, usePosition, etc.app/integrations/ - Stripe billing logic, Supabase storage helpers, external API clients.app/modules/ - Pure server-side domain logic (asset CRUD, booking management, permissions, search).app/routes/ - File-based React Router routes; _layout+/ contains all authenticated app routes.app/utils/ - Shared pure utilities: isFormProcessing, date helpers, CSV parsing, permission checks.desktop-app/ - Electron wrapper for an offline/desktop variant of the web app.server/ - Custom Node.js HTTP server bootstrapping React Router's request handler.sso/ - SAML/OIDC middleware and strategy configuration for enterprise SSO.scripts/ - One-off maintenance scripts: seed data, backfill migrations, QR batch generation.public/ - Publicly served static files: logo, OG images, PWA manifest, fonts.prisma.config.ts - Points Prisma CLI at the correct schema file path.react-router.config.ts - Enables SSR, sets appDirectory, configures future flags.vite.config.ts - Vite plugins for React Router, environment variable injection, build output.tailwind.config.ts - Theme tokens, custom colors, font sizes, plugin list.fly.toml - Fly.io deployment configuration (regions, scaling, health checks).docker-entrypoint.sh / start.sh - Container startup scripts for migration-then-serve flow.DATABASE_URL not set at build time — Prisma's generate step and route loaders both need DATABASE_URL; add it to your CI environment and to .env before npm run build.~/ path alias not resolved — Ensure vite.config.ts includes resolve.alias: { "~": path.resolve(__dirname, "app") } in addition to tsconfig.json paths; Vite and TypeScript resolve aliases independently.AssetImage component fetches signed URLs that expire.npx prisma generate after pulling new migrations; stale client types cause runtime type errors that TypeScript won't catch until tsc.useFetcher key collisions — Notes, BookingNotes, and AuditNotes all use the key "add-note" or "add-audit-note"; if you render multiple panels on one page, override the key prop or the optimistic UI state will bleed across panels.<AtomsResetHandler> (found in app/atoms/atoms-reset-handler.tsx) to prevent hydration mismatches on navigation.I have purchased the Shelf asset management web application source code.
The source is located at `source/` relative to this file, and integration
documentation is in `USAGE.md`.
The upstream project is `shelf` (backend domain), a React Router 7 / React 19
full-stack application using Prisma, Supabase, Tailwind CSS, Jotai, and Radix UI.
Please help me integrate this source into my existing project step by step:
1. Read `USAGE.md` fully before starting.
2. Identify which parts of `source/app/components/` I need for my use case: [DESCRIBE YOUR USE CASE].
3. Copy the relevant component directories into my project under `app/components/`.
4. Resolve all `~/` import aliases by ensuring my `tsconfig.json` and `vite.config.ts`
both map `~` to `./app`.
5. Install all required dependencies from the "Required dependencies" section of `USAGE.md`.
6. Wire up any required route loaders from `source/app/routes/` that the components
depend on (e.g., `assets.$assetId.activity` for the Notes component).
7. Add the necessary environment variables listed in `USAGE.md` to my `.env` file.
8. Run `npx prisma generate` and confirm the Prisma client is in sync.
9. Show me the minimal working route file that renders my chosen component.
10. Flag any pitfalls from the "Common pitfalls and fixes" section that apply to my setup.
My current stack: [DESCRIBE YOUR STACK — e.g., React Router 7, PostgreSQL, Node 20].
My target feature: [DESCRIBE — e.g., "add an asset notes/activity panel to my asset detail page"].
Shelf is released under the AGPL-3.0 license as noted in the repository. See source/LICENSE if present, or review the license at github.com/Shelf-nu/shelf.nu/blob/main/LICENSE. Upstream project: Shelf.nu on GitHub. Attribution to the Shelf.nu team is required when redistributing modified versions under AGPL-3.0.
This product’s unique contribution is clean room implementation of valuable code block into AVCP compatible standard.
完整安装指南与集成提示词将在购买后解锁。
CRM, ERP, Admin & Internal Tools
免费