Pinksheet is a PHP + SQLite inventory app for intake work, SKU lookup, photo management, legacy archive search, eBay prompt generation, Square sync, and backup/restore operations.
- Grayson's Guide
- Usage
- Schema
- Developer notes
- Testing
- Maintenance
- Operator SOP
- Archive workflow
- Backup and restore playbook
php -d upload_max_filesize=32M -d post_max_size=128M -d max_file_uploads=100 -S 127.0.0.1:8765 -t public public/router.phpOr on Windows:
.\serve.ps1Then open http://127.0.0.1:8765/ — no sign-in required, it just works.
/home.php— dashboard/intake.php?clear_draft=1— blank intake form/archive.php— legacy archive
Security model: the document root is
public/and every request is routed throughpublic/router.php, which whitelists entry points. The database, logs,.env, signing keys, scripts, and the bundled PHP runtime are never reachable over HTTP. There is no login — anyone who can reach the server can use the app. The Square webhook receiver is protected by its own HMAC signature verification. For an open-on-the-network app, keep it on a trusted LAN and expose it with HTTPS (see docs/ops.md).
index.phpandintake.phpprovide the intake sheet.home.phpandlookup.phpload the same dashboard shell;lookup.phpis the lookup-focused entry point.archive.phpshows the historical archive database.kanban.phpshows the status board.prompt_builder.phpbuilds the ChatGPT prompt and final eBay script.photo.php,download_photos.php,upload_photo.php,upload_photo_chunk.php, andset_thumbnail.phphandle photo storage and delivery.square_sync.php,sync_square_now.php, andscripts/sync_square.phphandle Square catalog sync.
data/intake.sqliteis the live working database.data/archive.sqliteis the standalone archive database used byarchive.php.data/sku_photos/stores uploaded photos on disk.data/chunks/is temporary storage for chunked uploads.data/backups/stores database backups and checksum files.logs/stores lookup, upload, and Square sync logs.
php scripts/migrate.php
php scripts/smoke.php
php scripts/build_archive_db.php
php scripts/check_db.php data/intake.sqlitePowerShell backup and verify helpers live in scripts/.
- Records are matched by normalized SKU.
- Autosave is server-backed and versioned.
- Photos are stored separately from the SQLite rows — and photos attach to a SKU as soon as you enter the SKU, no need to save first.
- The status board has a live filter (press
/to focus) and keyboard navigation (arrow keys move between cards,Enteropens a card in intake). - Archive rows are read-only in the UI.
- Backups are designed to be local-first, with optional mirrors.
- Square sync is optional and only runs when the local environment is configured.
- Autosave runs while you type and can restore the last draft after a clear.
- Copy fields from SKU loads the latest record for that SKU and excludes photos and database IDs.
- Bulk actions let you select rows, change status, or delete with a double confirmation.
scripts/backup.ps1defaults to no pruning and copies the database intodata/backups/.scripts/verify_backup.ps1andscripts/check_db.phpverify the live database and newest backup..githooks/pre-commitand.githooks/pre-pushare meant to keep live database files and backup files out of git history.backup_now.phpprovides the local-only Run backup now button on Home.
- Create a local
.envfile in the repo root and setSQUARE_ACCESS_TOKENandSQUARE_LOCATION_IDto enable sync. - Optional settings include
SQUARE_ENVIRONMENT,SQUARE_API_VERSION=2026-07-15,SQUARE_CURRENCY,SQUARE_DEFAULT_QUANTITY,SQUARE_SYNC_ENABLED, retry timeout settings, and signed webhook settings. - On save, quick edits, photo upload, and thumbnail changes, the app can upsert the matching Square catalog item and variation.
- Square sync metadata and last errors are stored in
square_catalog_sync. - Detailed sync errors are appended to
logs/square_sync.log.
Inbound Square sales are optional. To enable them, create a webhook subscription
in the Square Developer Dashboard at
https://your-domain.com/webhooks/square.php and add these .env values (never
commit the signature key):
SQUARE_WEBHOOK_SIGNATURE_KEY=
SQUARE_WEBHOOK_NOTIFICATION_URL=https://your-domain.com/webhooks/square.php
SQUARE_WEBHOOK_MAX_AGE_SECONDS=259200SQUARE_WEBHOOK_NOTIFICATION_URL must exactly match the subscription URL — the
receiver verifies Square's HMAC signature against it, and Square only delivers
over HTTPS. Completed payments record the sale in sales_history and mark the
mapped item SOLD; inventory events are stored for reconciliation only. See
operations for setup and testing.
docs/graysons-guide.md- the friendly handoff guide for future maintainers.docs/usage.md- core flows, themes, print guidance.docs/schema.md- intake_items, archive_items, Square sync, and database notes.docs/maintenance.md- backups, hooks, alerts, restore steps.docs/dev.md- file map, run instructions, smoke test.docs/ops.md- operator SOP: daily/weekly checks, backups, bulk delete safeguards, restore playbook.CHANGELOG.md- noteworthy UI and ops changes.