twotalesanimation 8a93a18bb9 Add REST API for quotes, shots, assets and tasks
Adds a key-authenticated REST API at /api/v1 so another system can create
and manage quotes without going through the UI.

Endpoints cover quotes (list, create, read, update, delete, recalculate),
shots, assets and line items, plus read-only clients and rate cards.
POST /api/v1/quotes builds a whole priced quote -- client, shots, assets
and tasks -- in a single transaction. Routes are also mounted under
/api/v1/jobs, since a quote and a job are the same record here.

Keys are stored as SHA-256 with a display prefix, so the plaintext is
shown once at creation and is not recoverable. They carry read/write
scopes, can be revoked (effective on the next request), and record when
they were last used. Minting and revoking live in Settings and are
restricted to signed-in admins.

/api/v1 is exempt from the session proxy because it authenticates with a
bearer key rather than a cookie -- without this, every API call was
redirected to /login as a 307. It is not unprotected: each route handler
requires a live, unrevoked key with the right scope.

Shot numbering and shot-code construction move into lib/shot-codes.ts so
the UI and the API cannot drift. This also fixes numbering restarting at
0010 when a scene was entered in a different case to the stored one: the
lookup upper-cased the scene but the stored value was left as typed.

Unspecified currency and markup/tax/discount on an API-created quote fall
back to the studio's configured quote defaults.

Decimal fields are serialised as strings to preserve the exact precision
the app's decimal arithmetic maintains.

Note: this needs `prisma migrate deploy` for the new api_keys table.
Settings will error for admins until that runs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-11-11 09:10:45 +02:00
2026-08-18 15:23:22 +02:00
2026-08-18 12:11:20 +02:00
2026-05-12 14:54:08 +02:00
2026-05-12 14:54:08 +02:00
2026-08-18 12:11:20 +02:00
2026-08-18 16:14:17 +02:00
2026-08-18 12:11:20 +02:00
2026-08-18 12:11:20 +02:00
2026-08-18 12:11:20 +02:00
2026-08-18 12:11:20 +02:00
2026-08-18 15:23:22 +02:00

xBid — VFX Quoting & Bidding SaaS

A professional full-stack VFX quoting application built with Next.js 15, TypeScript, Tailwind CSS v4, Prisma ORM, and PostgreSQL.


Features

  • Clients — manage client companies with full contact and billing info
  • Jobs / Quotes — versioned quote documents with status workflow (Draft ? Sent ? Approved/Rejected)
  • Shots — VFX shot breakdown with complexity multipliers and drag-and-drop reordering
  • Assets — CG asset budget tracking (characters, environments, vehicles, etc.)
  • Line Items — per-task cost rows with hours/days/artists/rates, markup, discount, tax
  • Rate Cards — studio rate card library organized by department
  • PDF Export — professional quote PDF with front page + detailed appendix
  • Decimal Precision — all financials use decimal.js (no floating-point drift)
  • REST API - create and manage quotes, shots, assets and tasks programmatically (API.md)

Tech Stack

Layer Technology
Framework Next.js 15 (App Router, Server Actions)
Language TypeScript
Styling Tailwind CSS v4 + shadcn/ui
ORM Prisma 7 + PostgreSQL 16
Forms React Hook Form + Zod
Drag & Drop @dnd-kit/core + @dnd-kit/sortable
Finance Math decimal.js
Notifications sonner
PDF HTML render via /api/pdf/[id]

Prerequisites

  • Node.js 20+
  • PostgreSQL 16 (or Docker)
  • npm 10+
  • ts-node for seeding: npm install -g ts-node typescript

Quick Start

1. Clone & install

git clone <repo-url>
cd xBid
npm install

2. Configure environment

cp .env.example .env

Edit .env:

DATABASE_URL="postgresql://postgres:postgres@localhost:5432/xbid"
NEXTAUTH_SECRET="your-random-secret-here"
NEXTAUTH_URL="http://localhost:3000"

3. Start PostgreSQL

Option A — Docker (recommended):

docker compose up -d postgres

Option B — local PostgreSQL:

CREATE DATABASE xbid;

4. Run database migrations

npm run db:generate   # generate Prisma client
npm run db:migrate    # run migrations (enter "init" as migration name)

5. Seed sample data

npm run db:seed

This creates 15 rate cards, 2 sample clients, 2 jobs with shots, assets, and line items.

6. Start development server

npm run dev

Open http://localhost:3000


Production (Docker)

docker compose up --build -d

After first run, apply migrations:

docker compose exec app npx prisma migrate deploy
docker compose exec app npx prisma db seed

PDF Export

Navigate to any job and click Download PDF. The route at /api/pdf/[id] generates HTML with:

  • Front page: client info, project details, shot/asset summary, financial totals, T&C
  • Appendix: full per-shot and per-asset line item breakdown

Print to PDF via browser (Ctrl+P ? Save as PDF).


REST API

xBid exposes a REST API at /api/v1 so another system can create and manage quotes, shots, assets and tasks without anyone opening the UI.

Requests authenticate with an API key, created under Settings -> API Keys (admins only):

curl -s http://localhost:3000/api/v1 \
  -H "Authorization: Bearer $XBID_API_KEY"

That endpoint lists every available route and confirms what the key may do. See API.md for the full reference: endpoints, pricing rules, shot code generation and error codes.

Note: GET_SHOTS.md documents the opposite direction - the review app's API that xBid pulls shots from.


Project Structure

src/
  app/                  Next.js App Router pages
    api/pdf/[id]/       PDF generation endpoint
    clients/            Client management
    jobs/               Job management
    rate-cards/         Rate card management
  actions/              Server actions (CRUD)
  components/
    assets/             Asset editor
    clients/            Client form & table
    dashboard/          Stats & recent jobs
    jobs/               Job form, table, detail, totals
    layout/             Sidebar navigation
    line-items/         Line item table & dialog
    rate-cards/         Rate card management
    shots/              Shot editor
    ui/                 shadcn/ui components
  lib/
    calculations.ts     Decimal.js financial math
    constants.ts        Domain constants & defaults
    prisma.ts           Prisma client singleton
    validations.ts      Zod schemas
prisma/
  schema.prisma         Full database schema
  seed.ts               Sample data seeder

Database Scripts

npm run db:generate   # npx prisma generate
npm run db:migrate    # npx prisma migrate dev
npm run db:seed       # ts-node prisma/seed.ts
npm run db:studio     # npx prisma studio (DB GUI at :5555)
S
Description
No description provided
Readme 535 KiB
Languages
TypeScript 98.8%
CSS 0.7%
JavaScript 0.4%
Dockerfile 0.1%