feat: add Stow prototype iOS app and Gin backend

This commit is contained in:
2026-10-02 21:23:31 +08:00
commit fe72c1ebd2
30 changed files with 3252 additions and 0 deletions
+68
View File
@@ -0,0 +1,68 @@
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE TABLE stow_users (
id VARCHAR(36) PRIMARY KEY,
"isAnonymous" BOOLEAN NOT NULL DEFAULT TRUE,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT now(),
"updatedAt" TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE stow_sessions (
id VARCHAR(36) PRIMARY KEY,
"userId" VARCHAR(36) NOT NULL REFERENCES stow_users(id) ON DELETE CASCADE,
"tokenHash" BYTEA NOT NULL UNIQUE,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT now(),
"expiresAt" TIMESTAMPTZ NOT NULL
);
CREATE INDEX stow_sessions_userId_idx ON stow_sessions ("userId");
CREATE TABLE stow_items (
id VARCHAR(36) PRIMARY KEY,
"userId" VARCHAR(36) NOT NULL REFERENCES stow_users(id) ON DELETE CASCADE,
"sourceType" VARCHAR(32) NOT NULL,
"sourceUrl" TEXT,
"primaryType" VARCHAR(32) NOT NULL DEFAULT 'other',
title TEXT NOT NULL,
summary TEXT NOT NULL DEFAULT '',
status VARCHAR(32) NOT NULL DEFAULT 'ready',
"ocrText" TEXT,
"searchText" TEXT NOT NULL DEFAULT '',
tags JSONB NOT NULL DEFAULT '[]'::jsonb,
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
"capturedAt" TIMESTAMPTZ,
"readyAt" TIMESTAMPTZ,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT now(),
"updatedAt" TIMESTAMPTZ NOT NULL DEFAULT now(),
"deletedAt" TIMESTAMPTZ,
version BIGINT NOT NULL DEFAULT 1
);
CREATE INDEX stow_items_userId_createdAt_idx ON stow_items ("userId", "createdAt" DESC) WHERE "deletedAt" IS NULL;
CREATE INDEX stow_items_userId_updatedAt_idx ON stow_items ("userId", "updatedAt", id);
CREATE INDEX stow_items_searchText_trgm_idx ON stow_items USING gin ("searchText" gin_trgm_ops) WHERE "deletedAt" IS NULL;
CREATE TABLE stow_assets (
id VARCHAR(36) PRIMARY KEY,
"itemId" VARCHAR(36) NOT NULL REFERENCES stow_items(id) ON DELETE CASCADE,
"objectKey" TEXT,
"thumbnailKey" TEXT,
"mimeType" VARCHAR(128),
width INTEGER,
height INTEGER,
"sizeBytes" BIGINT,
sha256 VARCHAR(64),
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE UNIQUE INDEX stow_assets_itemId_sha256_idx ON stow_assets ("itemId", sha256) WHERE sha256 IS NOT NULL;
CREATE TABLE stow_item_analyses (
id VARCHAR(36) PRIMARY KEY,
"itemId" VARCHAR(36) NOT NULL REFERENCES stow_items(id) ON DELETE CASCADE,
"pipelineVersion" VARCHAR(64) NOT NULL,
"promptVersion" VARCHAR(64),
"modelProvider" VARCHAR(64),
"modelName" VARCHAR(128),
"resultJson" JSONB NOT NULL,
confidence REAL,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX stow_item_analyses_itemId_createdAt_idx ON stow_item_analyses ("itemId", "createdAt" DESC);
@@ -0,0 +1,10 @@
ALTER TABLE stow_users ADD CONSTRAINT stow_users_id_uuid_check
CHECK (id ~* '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$');
ALTER TABLE stow_sessions ADD CONSTRAINT stow_sessions_id_uuid_check
CHECK (id ~* '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$');
ALTER TABLE stow_items ADD CONSTRAINT stow_items_id_uuid_check
CHECK (id ~* '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$');
ALTER TABLE stow_assets ADD CONSTRAINT stow_assets_id_uuid_check
CHECK (id ~* '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$');
ALTER TABLE stow_item_analyses ADD CONSTRAINT stow_item_analyses_id_uuid_check
CHECK (id ~* '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$');
@@ -0,0 +1,37 @@
ALTER TABLE stow_users RENAME COLUMN "isAnonymous" TO is_anonymous;
ALTER TABLE stow_users RENAME COLUMN "createdAt" TO created_at;
ALTER TABLE stow_users RENAME COLUMN "updatedAt" TO updated_at;
ALTER TABLE stow_sessions RENAME COLUMN "userId" TO user_id;
ALTER TABLE stow_sessions RENAME COLUMN "tokenHash" TO token_hash;
ALTER TABLE stow_sessions RENAME COLUMN "createdAt" TO created_at;
ALTER TABLE stow_sessions RENAME COLUMN "expiresAt" TO expires_at;
ALTER TABLE stow_items RENAME COLUMN "userId" TO user_id;
ALTER TABLE stow_items RENAME COLUMN "sourceType" TO source_type;
ALTER TABLE stow_items RENAME COLUMN "sourceUrl" TO source_url;
ALTER TABLE stow_items RENAME COLUMN "primaryType" TO primary_type;
ALTER TABLE stow_items RENAME COLUMN "ocrText" TO ocr_text;
ALTER TABLE stow_items RENAME COLUMN "searchText" TO search_text;
ALTER TABLE stow_items RENAME COLUMN "capturedAt" TO captured_at;
ALTER TABLE stow_items RENAME COLUMN "readyAt" TO ready_at;
ALTER TABLE stow_items RENAME COLUMN "createdAt" TO created_at;
ALTER TABLE stow_items RENAME COLUMN "updatedAt" TO updated_at;
ALTER TABLE stow_items RENAME COLUMN "deletedAt" TO deleted_at;
ALTER TABLE stow_assets RENAME COLUMN "itemId" TO item_id;
ALTER TABLE stow_assets RENAME COLUMN "objectKey" TO object_key;
ALTER TABLE stow_assets RENAME COLUMN "thumbnailKey" TO thumbnail_key;
ALTER TABLE stow_assets RENAME COLUMN "mimeType" TO mime_type;
ALTER TABLE stow_assets RENAME COLUMN "sizeBytes" TO size_bytes;
ALTER TABLE stow_assets RENAME COLUMN "createdAt" TO created_at;
ALTER TABLE stow_item_analyses RENAME COLUMN "itemId" TO item_id;
ALTER TABLE stow_item_analyses RENAME COLUMN "pipelineVersion" TO pipeline_version;
ALTER TABLE stow_item_analyses RENAME COLUMN "promptVersion" TO prompt_version;
ALTER TABLE stow_item_analyses RENAME COLUMN "modelProvider" TO model_provider;
ALTER TABLE stow_item_analyses RENAME COLUMN "modelName" TO model_name;
ALTER TABLE stow_item_analyses RENAME COLUMN "resultJson" TO result_json;
ALTER TABLE stow_item_analyses RENAME COLUMN "createdAt" TO created_at;
ALTER TABLE stow_schema_migrations RENAME COLUMN "appliedAt" TO applied_at;