mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
* feat(api): parse DATA_DIR from env for 1.x import auto-detection Claude-Session: https://claude.ai/code/session_01721WHAUGxnVk22qEeTub7w * test(migrator): build 1.17.2 fixtures by replaying legacy migrations Discovered the legacy migrations seed a Default team (0005) and builtin roles (0007), so the replayed fixture carries them. Seed uses a distinct custom team. Claude-Session: https://claude.ai/code/session_01721WHAUGxnVk22qEeTub7w * fix(migrator): self-adjusting column copy, jobs.status map, drop sessions, advisory lock The importer now inserts only the intersection of source and live target columns, so the three analytics_* columns 2.x dropped no longer break the first users INSERT (and future dropped columns are handled generically). jobs.status is mapped onto the 2.x enum (error->failed). Sessions are no longer migrated. A pg_advisory_xact_lock serializes concurrent replicas. Includes login-after-migrate and library assertions. Claude-Session: https://claude.ai/code/session_01721WHAUGxnVk22qEeTub7w * test(migrator): CI drift guard fails when a required column is unfillable from 1.17.2 Introspects every NOT-NULL-no-default column of each migrated table in the current schema and asserts the engine can fill it from a real 1.17.2 source. Turns a future breaking schema change into a PR-time failure instead of a production import break. Claude-Session: https://claude.ai/code/session_01721WHAUGxnVk22qEeTub7w * feat(migrator): orchestrator with detection, boot states, marker, blob count sqlite-import.ts owns source resolution (explicit path, 'off' sentinel, DATA_DIR probe), the four boot states (import/leftover/locked/none), the persisted sqlite_import marker, and a read-only library-blob count. runBootImport wires them together and catches TargetNonEmptyError as a benign multi-replica skip. Claude-Session: https://claude.ai/code/session_01721WHAUGxnVk22qEeTub7w * feat(api): route boot through the 1.x import orchestrator; hide marker from non-admins index.ts now calls runBootImport (which owns detection + the four boot states) instead of the inline SQLITE_MIGRATE_PATH block. The sqlite_import marker is added to SENSITIVE_KEYS (but not REDACTED_KEYS) so admins see the counts for the banner while non-admins don't see the key at all. Claude-Session: https://claude.ai/code/session_01721WHAUGxnVk22qEeTub7w * feat(migrator): add analyzeSqlite + dry-run/verify CLI analyzeSqlite is a read-only pre-flight (no live Postgres): per-table row counts, library-blob presence, and out-of-enum job statuses. The migrate:sqlite CLI now lives in the orchestrator and supports --dry-run/--verify (prints the analysis and exits without writing) alongside the existing import and --force. Claude-Session: https://claude.ai/code/session_01721WHAUGxnVk22qEeTub7w * docs: add 1.x to 2.0 upgrade guide; fix volume-name casing New apps/docs upgrade guide covering auto-detect, the SQLITE_MIGRATE_PATH override + off opt-out, the dry-run, what carries over, locked-state recovery, and non-destructive rollback. Leads with 'back up the WHOLE /data volume, not just snapotter.db' because 1.x WAL mode leaves data in snapotter.db-wal (surfaced by the real-image upgrade test). Standardizes README/DOCKERHUB compose volume names on the canonical SnapOtter-data casing so they match the repo compose and don't orphan an upgrader's volume. Claude-Session: https://claude.ai/code/session_01721WHAUGxnVk22qEeTub7w * feat(web): admin 1.x migration banner + 21-locale strings A one-time admin banner reads the sqlite_import marker from /v1/settings and shows the import result (user + saved-file counts) on success, or a warning when a 1.x database was found but not imported. Dismissal persists to a sqlite_import.dismissedAt settings key. shouldShowMigrationBanner/parseMigrationMarker sit in feedback.ts with the other shouldShow helpers; strings added to en.ts and all 20 other locales. Claude-Session: https://claude.ai/code/session_01721WHAUGxnVk22qEeTub7w * style(landing): biome-format Hero.astro trustBadges array Pre-existing formatting drift on main (its Lint check was skipped on the merge that introduced it); this PR's full Lint run surfaced it. Formatting-only, applied via the repo's own biome formatter to unblock the required Lint check. Claude-Session: https://claude.ai/code/session_01721WHAUGxnVk22qEeTub7w
97 lines
3.0 KiB
JSON
97 lines
3.0 KiB
JSON
{
|
|
"name": "@snapotter/api",
|
|
"version": "2.0.0",
|
|
"private": true,
|
|
"type": "module",
|
|
"scripts": {
|
|
"dev": "PORT=13490 tsx watch --import ./src/tracing.ts --import ./src/instrument.ts src/index.ts",
|
|
"build": "tsc",
|
|
"start": "tsx --import ./src/tracing.ts --import ./src/instrument.ts src/index.ts",
|
|
"lint": "biome check src/",
|
|
"typecheck": "tsc --noEmit",
|
|
"clean": "rm -rf dist",
|
|
"migrate:sqlite": "tsx src/db/sqlite-import.ts"
|
|
},
|
|
"dependencies": {
|
|
"@fastify/busboy": "^3.2.0",
|
|
"@fastify/cookie": "^11.0.2",
|
|
"@fastify/cors": "^11.0.0",
|
|
"@fastify/multipart": "^9.0.0",
|
|
"@fastify/rate-limit": "^10.2.0",
|
|
"@fastify/static": "^9.1.3",
|
|
"@neplex/vectorizer": "^0.1.0",
|
|
"@node-saml/node-saml": "^5.1.0",
|
|
"@opentelemetry/api": "^1.9.1",
|
|
"@opentelemetry/exporter-trace-otlp-http": "^0.219.0",
|
|
"@opentelemetry/instrumentation-aws-sdk": "^0.74.0",
|
|
"@opentelemetry/instrumentation-fastify": "^0.57.0",
|
|
"@opentelemetry/instrumentation-http": "^0.219.0",
|
|
"@opentelemetry/instrumentation-ioredis": "^0.67.0",
|
|
"@opentelemetry/instrumentation-pg": "^0.71.0",
|
|
"@opentelemetry/resources": "^2.8.0",
|
|
"@opentelemetry/sdk-node": "^0.219.0",
|
|
"@opentelemetry/sdk-trace-base": "^2.8.0",
|
|
"@opentelemetry/semantic-conventions": "^1.41.1",
|
|
"@scalar/fastify-api-reference": "^1.62.0",
|
|
"@sentry/node": "^10.62.0",
|
|
"@snapotter/ai": "workspace:*",
|
|
"@snapotter/doc-engine": "workspace:*",
|
|
"@snapotter/enterprise": "workspace:*",
|
|
"@snapotter/image-engine": "workspace:*",
|
|
"@snapotter/media-engine": "workspace:*",
|
|
"@snapotter/shared": "workspace:*",
|
|
"archiver": "^7.0.1",
|
|
"better-sqlite3": "^11.7.0",
|
|
"bullmq": "^5.79.2",
|
|
"bwip-js": "^4.11.1",
|
|
"dotenv": "^16.4.0",
|
|
"drizzle-orm": "^0.45.2",
|
|
"exceljs": "^4.4.0",
|
|
"exif-reader": "^2.0.3",
|
|
"fast-xml-parser": "^5.9.3",
|
|
"fastify": "^5.9.0",
|
|
"fflate": "^0.8.3",
|
|
"ioredis": "^5.11.1",
|
|
"ipaddr.js": "^2.4.0",
|
|
"js-yaml": "^4.3.0",
|
|
"mupdf": "^1.27.0",
|
|
"openid-client": "^6.8.4",
|
|
"opentype.js": "^2.0.0",
|
|
"otpauth": "^9.5.1",
|
|
"p-queue": "^9.3.0",
|
|
"papaparse": "^5.5.4",
|
|
"pdfkit": "^0.19.1",
|
|
"pg": "^8.22.0",
|
|
"pino": "^10.3.1",
|
|
"pino-roll": "^4.0.0",
|
|
"playwright": "^1.61.1",
|
|
"posthog-node": "^5.38.6",
|
|
"potrace": "^2.1.8",
|
|
"prom-client": "^15.1.3",
|
|
"qrcode": "^1.5.4",
|
|
"sharp": "^0.35.2",
|
|
"tar": "^7.5.19",
|
|
"tsx": "^4.22.4",
|
|
"yauzl": "^3.4.0",
|
|
"zod": "^3.24.0",
|
|
"zxing-wasm": "^3.1.0"
|
|
},
|
|
"devDependencies": {
|
|
"@types/archiver": "^7.0.0",
|
|
"@types/better-sqlite3": "^7.6.0",
|
|
"@types/js-yaml": "^4.0.9",
|
|
"@types/node": "^22.20.0",
|
|
"@types/opentype.js": "^1.3.10",
|
|
"@types/papaparse": "^5.5.2",
|
|
"@types/pdfkit": "^0.17.6",
|
|
"@types/pg": "^8.20.0",
|
|
"@types/potrace": "^2.1.5",
|
|
"@types/qrcode": "^1.5.6",
|
|
"@types/tar": "^7.0.87",
|
|
"@types/yauzl": "^3.4.0",
|
|
"drizzle-kit": "^0.31.0",
|
|
"typescript": "^5.7.0"
|
|
},
|
|
"license": "AGPL-3.0"
|
|
}
|