From f2ac1c426ee48fbbe0d0e6e68b294064d70f4e6c Mon Sep 17 00:00:00 2001 From: francy51 Date: Thu, 26 Feb 2026 15:45:22 -0500 Subject: [PATCH] Migrate stack to SQLite and set Coolify defaults --- .env.example | 24 +- .gitignore | 1 + Dockerfile | 6 +- README.md | 61 +- bun.lock | 119 +- docker-compose.yml | 36 +- drizzle.config.ts | 8 +- drizzle/0000_cold_silver_centurion.sql | 190 +++ drizzle/0000_tense_centennial.sql | 199 ---- drizzle/0001_boring_toad.sql | 94 -- drizzle/meta/0000_snapshot.json | 1038 ++++++++++++---- drizzle/meta/0001_snapshot.json | 1502 ------------------------ drizzle/meta/_journal.json | 15 +- lib/auth.ts | 2 +- lib/server/db/index.ts | 47 +- lib/server/db/schema.ts | 131 +-- package.json | 8 +- tsconfig.json | 3 + 18 files changed, 1266 insertions(+), 2218 deletions(-) create mode 100644 drizzle/0000_cold_silver_centurion.sql delete mode 100644 drizzle/0000_tense_centennial.sql delete mode 100644 drizzle/0001_boring_toad.sql delete mode 100644 drizzle/meta/0001_snapshot.json diff --git a/.env.example b/.env.example index c4fd891..74e6850 100644 --- a/.env.example +++ b/.env.example @@ -4,16 +4,13 @@ NEXT_PUBLIC_API_URL= # Local docker host port (used by docker-compose.override.yml) APP_PORT=3000 -# Better Auth / PostgreSQL -# For app running outside Docker, localhost is typical. -# In Docker Compose deployment, default internal host is: postgres -DATABASE_URL=postgres://postgres:postgres@localhost:5432/fiscal_clone -POSTGRES_DB=fiscal_clone -POSTGRES_USER=postgres -POSTGRES_PASSWORD=postgres +# Better Auth / SQLite +# For app running outside Docker, this resolves to ./data/fiscal.sqlite +# In Docker Compose deployment, default path is /app/data/fiscal.sqlite +DATABASE_URL=file:data/fiscal.sqlite BETTER_AUTH_SECRET=replace-with-a-long-random-secret -BETTER_AUTH_BASE_URL=http://localhost:3000 -BETTER_AUTH_TRUSTED_ORIGINS=http://localhost:3000 +BETTER_AUTH_BASE_URL=https://fiscal.b11studio.xyz +BETTER_AUTH_TRUSTED_ORIGINS=https://fiscal.b11studio.xyz # OpenClaw / ZeroClaw (OpenAI-compatible) OPENCLAW_BASE_URL=http://localhost:4000 @@ -23,8 +20,7 @@ OPENCLAW_MODEL=zeroclaw # SEC API etiquette SEC_USER_AGENT=Fiscal Clone -# Workflow runtime (Postgres world) -WORKFLOW_TARGET_WORLD=@workflow/world-postgres -WORKFLOW_POSTGRES_URL=postgres://postgres:postgres@localhost:5432/fiscal_clone -WORKFLOW_POSTGRES_JOB_PREFIX=fiscal_clone -WORKFLOW_POSTGRES_WORKER_CONCURRENCY=10 +# Workflow runtime (Local world) +WORKFLOW_TARGET_WORLD=local +WORKFLOW_LOCAL_DATA_DIR=.workflow-data +WORKFLOW_LOCAL_QUEUE_CONCURRENCY=100 diff --git a/.gitignore b/.gitignore index bcfe1d8..679496a 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,4 @@ out/ # Local app runtime state data/*.json +.workflow-data/ diff --git a/Dockerfile b/Dockerfile index 9cfab07..eae00e1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ RUN bun install --frozen-lockfile FROM deps AS builder ARG NEXT_PUBLIC_API_URL= -ARG DATABASE_URL=postgres://postgres:postgres@localhost:5432/fiscal_clone +ARG DATABASE_URL=file:data/fiscal.sqlite ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} ENV DATABASE_URL=${DATABASE_URL} ENV NEXT_TELEMETRY_DISABLED=1 @@ -29,8 +29,10 @@ COPY --from=deps /app/node_modules ./node_modules COPY --from=deps /app/package.json ./package.json COPY --from=deps /app/bun.lock ./bun.lock +RUN mkdir -p /app/data /app/.workflow-data + EXPOSE 3000 ENV PORT=3000 -CMD ["sh", "-c", "./node_modules/.bin/drizzle-kit migrate --config /app/drizzle.config.ts && ./node_modules/.bin/workflow-postgres-setup && bun server.js"] +CMD ["sh", "-c", "./node_modules/.bin/drizzle-kit migrate --config /app/drizzle.config.ts && bun server.js"] diff --git a/README.md b/README.md index a6b21e1..1863d5a 100644 --- a/README.md +++ b/README.md @@ -9,30 +9,25 @@ Turbopack-first rebuild of a fiscal.ai-style terminal with OpenClaw integration. - Elysia route layer mounted in Next Route Handlers - Turbopack for `dev` and `build` - Better Auth (email/password + magic link) -- Drizzle ORM (PostgreSQL) + Better Auth Drizzle adapter +- Drizzle ORM (SQLite) + Better Auth Drizzle adapter - Internal API routes via Elysia app module (`lib/server/api/app.ts`) - Eden Treaty for type-safe frontend API calls -- Workflow DevKit + Postgres World for durable background task execution -- PostgreSQL-backed domain storage (watchlist, holdings, filings, tasks, insights) +- Workflow DevKit Local World for background task execution +- SQLite-backed domain storage (watchlist, holdings, filings, tasks, insights) - OpenClaw/ZeroClaw analysis via OpenAI-compatible chat endpoint ## Run locally ```bash bun install +bun run db:generate +bun run db:migrate bun run dev ``` Open [http://localhost:3000](http://localhost:3000). -Better Auth requires PostgreSQL. Set `DATABASE_URL`, `BETTER_AUTH_SECRET`, and `BETTER_AUTH_BASE_URL` in `.env.local`. -Generate/apply schema migrations and set up the workflow world tables before starting the app: - -```bash -bun run db:generate -bun run db:migrate -bun run workflow:setup -``` +The default database path is `data/fiscal.sqlite` via `DATABASE_URL=file:data/fiscal.sqlite`. ## Production build @@ -50,12 +45,32 @@ docker compose up --build -d ``` For local Docker, host port mapping comes from `docker-compose.override.yml` (default `http://localhost:3000`, configurable via `APP_PORT`). -The base Docker Compose now includes an internal PostgreSQL service (`postgres`) used by Better Auth by default. -On container startup, the app now applies Drizzle migrations automatically before launching Next.js. -For Coolify/remote Docker Compose, only app container port `3000` is exposed internally (no fixed host port bind), avoiding host port collisions. -If you use an external Postgres instance, set `DATABASE_URL` explicitly. +On container startup, the app applies Drizzle migrations automatically before launching Next.js. +The app stores SQLite data in Docker volume `fiscal_sqlite_data` (mounted to `/app/data`) and workflow local data in `fiscal_workflow_data` (mounted to `/app/.workflow-data`). + +Workflow Local World uses filesystem state plus an in-memory queue. On container restart, queued in-flight jobs may be lost. + Docker images use Bun (`oven/bun:1.3.5-alpine`) for build and runtime. +## Coolify deployment + +This compose setup is compatible with Coolify as-is (it uses named Docker volumes, not host bind mounts). + +Required environment variables in Coolify: + +- `DATABASE_URL=file:/app/data/fiscal.sqlite` +- `BETTER_AUTH_SECRET=` +- `BETTER_AUTH_BASE_URL=https://fiscal.b11studio.xyz` +- `BETTER_AUTH_TRUSTED_ORIGINS=https://fiscal.b11studio.xyz` +- `WORKFLOW_TARGET_WORLD=local` +- Optional: `WORKFLOW_LOCAL_DATA_DIR=/app/.workflow-data` + +Operational constraints for Coolify: + +- Keep this service to a single instance/replica. SQLite is file-based and not appropriate for multi-replica shared-write deployments. +- Ensure the two named volumes are persisted (`fiscal_sqlite_data`, `fiscal_workflow_data`). +- Workflow Local queueing is in-memory; in-flight queued jobs may be lost on restarts. + ## Environment Use root `.env` or root `.env.local`: @@ -63,23 +78,19 @@ Use root `.env` or root `.env.local`: ```env # leave blank for same-origin API NEXT_PUBLIC_API_URL= -DATABASE_URL=postgres://postgres:postgres@localhost:5432/fiscal_clone -POSTGRES_DB=fiscal_clone -POSTGRES_USER=postgres -POSTGRES_PASSWORD=postgres +DATABASE_URL=file:data/fiscal.sqlite BETTER_AUTH_SECRET=replace-with-a-long-random-secret -BETTER_AUTH_BASE_URL=http://localhost:3000 -BETTER_AUTH_TRUSTED_ORIGINS=http://localhost:3000 +BETTER_AUTH_BASE_URL=https://fiscal.b11studio.xyz +BETTER_AUTH_TRUSTED_ORIGINS=https://fiscal.b11studio.xyz OPENCLAW_BASE_URL=http://localhost:4000 OPENCLAW_API_KEY=your_key OPENCLAW_MODEL=zeroclaw SEC_USER_AGENT=Fiscal Clone -WORKFLOW_TARGET_WORLD=@workflow/world-postgres -WORKFLOW_POSTGRES_URL=postgres://postgres:postgres@localhost:5432/fiscal_clone -WORKFLOW_POSTGRES_JOB_PREFIX=fiscal_clone -WORKFLOW_POSTGRES_WORKER_CONCURRENCY=10 +WORKFLOW_TARGET_WORLD=local +WORKFLOW_LOCAL_DATA_DIR=.workflow-data +WORKFLOW_LOCAL_QUEUE_CONCURRENCY=100 ``` If OpenClaw is unset, the app uses local fallback analysis so task workflows still run. diff --git a/bun.lock b/bun.lock index b8a79d9..ea05ad8 100644 --- a/bun.lock +++ b/bun.lock @@ -6,8 +6,8 @@ "name": "fiscal-frontend", "dependencies": { "@elysiajs/eden": "^1.4.8", + "@libsql/client": "^0.17.0", "@tailwindcss/postcss": "^4.2.1", - "@workflow/world-postgres": "^4.1.0-beta.36", "better-auth": "^1.4.19", "clsx": "^2.1.1", "date-fns": "^4.1.0", @@ -15,7 +15,6 @@ "elysia": "latest", "lucide-react": "^0.575.0", "next": "^16.1.6", - "pg": "^8.18.0", "react": "^19.2.4", "react-dom": "^19.2.4", "recharts": "^3.7.0", @@ -23,10 +22,10 @@ }, "devDependencies": { "@types/node": "^25.3.0", - "@types/pg": "^8.16.0", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", "autoprefixer": "^10.4.24", + "bun-types": "^1.3.10", "drizzle-kit": "^0.31.4", "postcss": "^8.5.6", "tailwindcss": "^4.2.1", @@ -241,6 +240,32 @@ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + "@libsql/client": ["@libsql/client@0.17.0", "", { "dependencies": { "@libsql/core": "^0.17.0", "@libsql/hrana-client": "^0.9.0", "js-base64": "^3.7.5", "libsql": "^0.5.22", "promise-limit": "^2.7.0" } }, "sha512-TLjSU9Otdpq0SpKHl1tD1Nc9MKhrsZbCFGot3EbCxRa8m1E5R1mMwoOjKMMM31IyF7fr+hPNHLpYfwbMKNusmg=="], + + "@libsql/core": ["@libsql/core@0.17.0", "", { "dependencies": { "js-base64": "^3.7.5" } }, "sha512-hnZRnJHiS+nrhHKLGYPoJbc78FE903MSDrFJTbftxo+e52X+E0Y0fHOCVYsKWcg6XgB7BbJYUrz/xEkVTSaipw=="], + + "@libsql/darwin-arm64": ["@libsql/darwin-arm64@0.5.22", "", { "os": "darwin", "cpu": "arm64" }, "sha512-4B8ZlX3nIDPndfct7GNe0nI3Yw6ibocEicWdC4fvQbSs/jdq/RC2oCsoJxJ4NzXkvktX70C1J4FcmmoBy069UA=="], + + "@libsql/darwin-x64": ["@libsql/darwin-x64@0.5.22", "", { "os": "darwin", "cpu": "x64" }, "sha512-ny2HYWt6lFSIdNFzUFIJ04uiW6finXfMNJ7wypkAD8Pqdm6nAByO+Fdqu8t7sD0sqJGeUCiOg480icjyQ2/8VA=="], + + "@libsql/hrana-client": ["@libsql/hrana-client@0.9.0", "", { "dependencies": { "@libsql/isomorphic-ws": "^0.1.5", "cross-fetch": "^4.0.0", "js-base64": "^3.7.5", "node-fetch": "^3.3.2" } }, "sha512-pxQ1986AuWfPX4oXzBvLwBnfgKDE5OMhAdR/5cZmRaB4Ygz5MecQybvwZupnRz341r2CtFmbk/BhSu7k2Lm+Jw=="], + + "@libsql/isomorphic-ws": ["@libsql/isomorphic-ws@0.1.5", "", { "dependencies": { "@types/ws": "^8.5.4", "ws": "^8.13.0" } }, "sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg=="], + + "@libsql/linux-arm-gnueabihf": ["@libsql/linux-arm-gnueabihf@0.5.22", "", { "os": "linux", "cpu": "arm" }, "sha512-3Uo3SoDPJe/zBnyZKosziRGtszXaEtv57raWrZIahtQDsjxBVjuzYQinCm9LRCJCUT5t2r5Z5nLDPJi2CwZVoA=="], + + "@libsql/linux-arm-musleabihf": ["@libsql/linux-arm-musleabihf@0.5.22", "", { "os": "linux", "cpu": "arm" }, "sha512-LCsXh07jvSojTNJptT9CowOzwITznD+YFGGW+1XxUr7fS+7/ydUrpDfsMX7UqTqjm7xG17eq86VkWJgHJfvpNg=="], + + "@libsql/linux-arm64-gnu": ["@libsql/linux-arm64-gnu@0.5.22", "", { "os": "linux", "cpu": "arm64" }, "sha512-KSdnOMy88c9mpOFKUEzPskSaF3VLflfSUCBwas/pn1/sV3pEhtMF6H8VUCd2rsedwoukeeCSEONqX7LLnQwRMA=="], + + "@libsql/linux-arm64-musl": ["@libsql/linux-arm64-musl@0.5.22", "", { "os": "linux", "cpu": "arm64" }, "sha512-mCHSMAsDTLK5YH//lcV3eFEgiR23Ym0U9oEvgZA0667gqRZg/2px+7LshDvErEKv2XZ8ixzw3p1IrBzLQHGSsw=="], + + "@libsql/linux-x64-gnu": ["@libsql/linux-x64-gnu@0.5.22", "", { "os": "linux", "cpu": "x64" }, "sha512-kNBHaIkSg78Y4BqAdgjcR2mBilZXs4HYkAmi58J+4GRwDQZh5fIUWbnQvB9f95DkWUIGVeenqLRFY2pcTmlsew=="], + + "@libsql/linux-x64-musl": ["@libsql/linux-x64-musl@0.5.22", "", { "os": "linux", "cpu": "x64" }, "sha512-UZ4Xdxm4pu3pQXjvfJiyCzZop/9j/eA2JjmhMaAhe3EVLH2g11Fy4fwyUp9sT1QJYR1kpc2JLuybPM0kuXv/Tg=="], + + "@libsql/win32-x64-msvc": ["@libsql/win32-x64-msvc@0.5.22", "", { "os": "win32", "cpu": "x64" }, "sha512-Fj0j8RnBpo43tVZUVoNK6BV/9AtDUM5S7DF3LB4qTYg1LMSZqi3yeCneUTLJD6XomQJlZzbI4mst89yspVSAnA=="], + "@lukeed/csprng": ["@lukeed/csprng@1.1.0", "", {}, "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA=="], "@mjackson/node-fetch-server": ["@mjackson/node-fetch-server@0.2.0", "", {}, "sha512-EMlH1e30yzmTpGLQjlFmaDAjyOeZhng1/XCd7DExR8PNAnG/G1tyruZxEoUe11ClnwGhGrtsdnyyUx1frSzjng=="], @@ -281,6 +306,8 @@ "@napi-rs/nice-win32-x64-msvc": ["@napi-rs/nice-win32-x64-msvc@1.1.1", "", { "os": "win32", "cpu": "x64" }, "sha512-vB+4G/jBQCAh0jelMTY3+kgFy00Hlx2f2/1zjMoH821IbplbWZOkLiTYXQkygNTzQJTq5cvwBDgn2ppHD+bglQ=="], + "@neon-rs/load": ["@neon-rs/load@0.0.4", "", {}, "sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw=="], + "@nestjs/common": ["@nestjs/common@11.1.14", "", { "dependencies": { "file-type": "21.3.0", "iterare": "1.2.1", "load-esm": "1.0.3", "tslib": "2.8.1", "uid": "2.0.2" }, "peerDependencies": { "class-transformer": ">=0.4.1", "class-validator": ">=0.13.2", "reflect-metadata": "^0.1.12 || ^0.2.0", "rxjs": "^7.1.0" }, "optionalPeers": ["class-transformer", "class-validator"] }, "sha512-IN/tlqd7Nl9gl6f0jsWEuOrQDaCI9vHzxv0fisHysfBQzfQIkqlv5A7w4Qge02BUQyczXT9HHPgHtWHCxhjRng=="], "@nestjs/core": ["@nestjs/core@11.1.14", "", { "dependencies": { "@nuxt/opencollective": "0.4.1", "fast-safe-stringify": "2.1.1", "iterare": "1.2.1", "path-to-regexp": "8.3.0", "tslib": "2.8.1", "uid": "2.0.2" }, "peerDependencies": { "@nestjs/common": "^11.0.0", "@nestjs/microservices": "^11.0.0", "@nestjs/platform-express": "^11.0.0", "@nestjs/websockets": "^11.0.0", "reflect-metadata": "^0.1.12 || ^0.2.0", "rxjs": "^7.1.0" }, "optionalPeers": ["@nestjs/microservices", "@nestjs/platform-express", "@nestjs/websockets"] }, "sha512-7OXPPMoDr6z+5NkoQKu4hOhfjz/YYqM3bNilPqv1WVFWrzSmuNXxvhbX69YMmNmRYascPXiwESqf5jJdjKXEww=="], @@ -513,11 +540,13 @@ "@types/use-sync-external-store": ["@types/use-sync-external-store@0.0.6", "", {}, "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg=="], + "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], + "@vercel/cli-auth": ["@vercel/cli-auth@0.0.1", "", { "dependencies": { "async-listen": "3.0.0", "open": "8.4.0", "xdg-app-paths": "5", "zod": "4.1.11" } }, "sha512-CnqiuMlZ4pjs2LCPYiR6aLKPPd3Xb8SBI1Y7eotXKgpx6qgrGNY+E7EIyUt5ErGHJGIrCZyGG5WEo4bHtVmz2Q=="], "@vercel/functions": ["@vercel/functions@3.4.3", "", { "dependencies": { "@vercel/oidc": "3.2.0" }, "peerDependencies": { "@aws-sdk/credential-provider-web-identity": "*" }, "optionalPeers": ["@aws-sdk/credential-provider-web-identity"] }, "sha512-kA14KIUVgAY6VXbhZ5jjY+s0883cV3cZqIU3WhrSRxuJ9KvxatMjtmzl0K23HK59oOUjYl7HaE/eYMmhmqpZzw=="], - "@vercel/oidc": ["@vercel/oidc@3.2.0", "", {}, "sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug=="], + "@vercel/oidc": ["@vercel/oidc@3.0.5", "", {}, "sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw=="], "@vercel/queue": ["@vercel/queue@0.0.0-alpha.38", "", { "dependencies": { "@vercel/oidc": "^3.0.5", "mixpart": "0.0.5-alpha.1" } }, "sha512-gSYpZrYy1LpzfXqDMUZX7xEIQxyhelvMDgthxijs495kHIxWC65S0C3vaAw5+3c1ujbPeJgLz8fn3SDTJspssw=="], @@ -559,8 +588,6 @@ "@workflow/world-local": ["@workflow/world-local@4.1.0-beta.34", "", { "dependencies": { "@vercel/queue": "0.0.0-alpha.38", "@workflow/errors": "4.1.0-beta.16", "@workflow/utils": "4.1.0-beta.12", "@workflow/world": "4.1.0-beta.6", "async-sema": "3.1.1", "ulid": "3.0.1", "undici": "6.22.0", "zod": "4.1.11" }, "peerDependencies": { "@opentelemetry/api": "1" }, "optionalPeers": ["@opentelemetry/api"] }, "sha512-ZwIWBs4m/1HNy8PeP0h63Q47Sx1XragGzTF+saiHiCZP5sLZJz8veOrXhJ7tqdJBoIhp3pm5GsTes/NpGYXClg=="], - "@workflow/world-postgres": ["@workflow/world-postgres@4.1.0-beta.36", "", { "dependencies": { "@vercel/queue": "0.0.0-alpha.38", "@workflow/errors": "4.1.0-beta.16", "@workflow/world": "4.1.0-beta.6", "@workflow/world-local": "4.1.0-beta.34", "cbor-x": "1.6.0", "dotenv": "16.4.5", "drizzle-orm": "0.44.7", "pg-boss": "11.0.7", "postgres": "3.4.7", "ulid": "3.0.1", "zod": "4.1.11" }, "bin": { "workflow-postgres-setup": "bin/setup.js" } }, "sha512-Dwc6MRwS5FaLWUwApyzemqvGD3fIw1axnvpaQCwADs73GJ7s5LWvctK5kNobCgF04ZYyF4IhqbY1T+r8P04Uaw=="], - "@workflow/world-vercel": ["@workflow/world-vercel@4.1.0-beta.34", "", { "dependencies": { "@vercel/oidc": "3.0.5", "@vercel/queue": "0.0.0-alpha.38", "@workflow/errors": "4.1.0-beta.16", "@workflow/world": "4.1.0-beta.6", "cbor-x": "1.6.0", "zod": "4.1.11" }, "peerDependencies": { "@opentelemetry/api": "1" }, "optionalPeers": ["@opentelemetry/api"] }, "sha512-1BmBZ4MsuvcHCk0sOL1lX5JyxH3qs0oB1ZeWaKykJWhFn2Cl6t2fLBSl9lbBLDTwHMiK7caowGPnzH2Yxw4Etg=="], "@xhmikosr/archive-type": ["@xhmikosr/archive-type@7.1.0", "", { "dependencies": { "file-type": "^20.5.0" } }, "sha512-xZEpnGplg1sNPyEgFh0zbHxqlw5dtYg6viplmWSxUj12+QjU9SKu3U/2G73a15pEjLaOqTefNSZ1fOPUOT4Xgg=="], @@ -651,6 +678,8 @@ "builtin-modules": ["builtin-modules@5.0.0", "", {}, "sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg=="], + "bun-types": ["bun-types@1.3.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg=="], + "bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="], "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], @@ -715,7 +744,7 @@ "cosmiconfig": ["cosmiconfig@9.0.0", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg=="], - "cron-parser": ["cron-parser@5.5.0", "", { "dependencies": { "luxon": "^3.7.1" } }, "sha512-oML4lKUXxizYswqmxuOCpgFS8BNUJpIu6k/2HVHyaL8Ynnf3wdf9tkns0yRdJLSIjkJ+b0DXHMZEHGpMwjnPww=="], + "cross-fetch": ["cross-fetch@4.1.0", "", { "dependencies": { "node-fetch": "^2.7.0" } }, "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw=="], "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], @@ -743,6 +772,8 @@ "d3-timer": ["d3-timer@3.0.1", "", {}, "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="], + "data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="], + "date-fns": ["date-fns@4.1.0", "", {}, "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg=="], "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], @@ -769,13 +800,13 @@ "destroy": ["destroy@1.2.0", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="], - "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + "detect-libc": ["detect-libc@2.0.2", "", {}, "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw=="], "devalue": ["devalue@5.6.0", "", {}, "sha512-BaD1s81TFFqbD6Uknni42TrolvEWA1Ih5L+OiHWmi4OYMJVwAYPGtha61I9KxTf52OvVHozHyjPu8zljqdF3uA=="], "dir-glob": ["dir-glob@3.0.1", "", { "dependencies": { "path-type": "^4.0.0" } }, "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="], - "dotenv": ["dotenv@16.4.5", "", {}, "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg=="], + "dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="], "drizzle-kit": ["drizzle-kit@0.31.9", "", { "dependencies": { "@drizzle-team/brocli": "^0.10.2", "@esbuild-kit/esm-loader": "^2.5.5", "esbuild": "^0.25.4", "esbuild-register": "^3.5.0" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-GViD3IgsXn7trFyBUUHyTFBpH/FsHTxYJ66qdbVggxef4UBPHRYxQaRzYLTuekYnk9i5FIEL9pbBIwMqX/Uwrg=="], @@ -859,6 +890,8 @@ "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + "fetch-blob": ["fetch-blob@3.2.0", "", { "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" } }, "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ=="], + "fflate": ["fflate@0.8.2", "", {}, "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="], "file-type": ["file-type@21.3.0", "", { "dependencies": { "@tokenizer/inflate": "^0.4.1", "strtok3": "^10.3.4", "token-types": "^6.1.1", "uint8array-extras": "^1.4.0" } }, "sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA=="], @@ -879,6 +912,8 @@ "form-data-encoder": ["form-data-encoder@2.1.4", "", {}, "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw=="], + "formdata-polyfill": ["formdata-polyfill@4.0.10", "", { "dependencies": { "fetch-blob": "^3.1.2" } }, "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g=="], + "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="], "fraction.js": ["fraction.js@5.3.4", "", {}, "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ=="], @@ -985,6 +1020,8 @@ "jose": ["jose@6.1.3", "", {}, "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ=="], + "js-base64": ["js-base64@3.7.8", "", {}, "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow=="], + "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], @@ -1007,6 +1044,8 @@ "kysely": ["kysely@0.28.11", "", {}, "sha512-zpGIFg0HuoC893rIjYX1BETkVWdDnzTzF5e0kWXJFg5lE0k1/LfNWBejrcnOFu8Q2Rfq/hTDTU7XLUM8QOrpzg=="], + "libsql": ["libsql@0.5.22", "", { "dependencies": { "@neon-rs/load": "^0.0.4", "detect-libc": "2.0.2" }, "optionalDependencies": { "@libsql/darwin-arm64": "0.5.22", "@libsql/darwin-x64": "0.5.22", "@libsql/linux-arm-gnueabihf": "0.5.22", "@libsql/linux-arm-musleabihf": "0.5.22", "@libsql/linux-arm64-gnu": "0.5.22", "@libsql/linux-arm64-musl": "0.5.22", "@libsql/linux-x64-gnu": "0.5.22", "@libsql/linux-x64-musl": "0.5.22", "@libsql/win32-x64-msvc": "0.5.22" }, "os": [ "linux", "win32", "darwin", ], "cpu": [ "arm", "x64", "arm64", ] }, "sha512-NscWthMQt7fpU8lqd7LXMvT9pi+KhhmTHAJWUB/Lj6MWa0MKFv0F2V4C6WKKpjCVZl0VwcDz4nOI3CyaT1DDiA=="], + "lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="], "lightningcss-android-arm64": ["lightningcss-android-arm64@1.31.1", "", { "os": "android", "cpu": "arm64" }, "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg=="], @@ -1043,8 +1082,6 @@ "lucide-react": ["lucide-react@0.575.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-VuXgKZrk0uiDlWjGGXmKV6MSk9Yy4l10qgVvzGn2AWBx1Ylt0iBexKOAoA6I7JO3m+M9oeovJd3yYENfkUbOeg=="], - "luxon": ["luxon@3.7.2", "", {}, "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew=="], - "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], @@ -1077,7 +1114,7 @@ "minimatch": ["minimatch@9.0.8", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-reYkDYtj/b19TeqbNZCV4q9t+Yxylf/rYBsLb42SXJatTv4/ylq5lEiAmhA/IToxO7NI2UzNMghHoHuaqDkAjw=="], - "mixpart": ["mixpart@0.0.5-alpha.1", "", {}, "sha512-2ZfG/NO2SVE9HLk1/W+yOrIOA0d674ljZExLdievZQpYjbJYQjIdye8vNMR63yF7nN/NbO9q8mp16JUEYBCilg=="], + "mixpart": ["mixpart@0.0.4", "", {}, "sha512-RAoaOSXnMLrfUfmFbNynRYjeMru/bhgAYRy/GQVI8gmRq7vm9V9c2gGVYnYoQ008X6YTmRIu5b0397U7vb0bIA=="], "mlly": ["mlly@1.8.0", "", { "dependencies": { "acorn": "^8.15.0", "pathe": "^2.0.3", "pkg-types": "^1.3.1", "ufo": "^1.6.1" } }, "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g=="], @@ -1091,6 +1128,10 @@ "next": ["next@16.1.6", "", { "dependencies": { "@next/env": "16.1.6", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.1.6", "@next/swc-darwin-x64": "16.1.6", "@next/swc-linux-arm64-gnu": "16.1.6", "@next/swc-linux-arm64-musl": "16.1.6", "@next/swc-linux-x64-gnu": "16.1.6", "@next/swc-linux-x64-musl": "16.1.6", "@next/swc-win32-arm64-msvc": "16.1.6", "@next/swc-win32-x64-msvc": "16.1.6", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": "dist/bin/next" }, "sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw=="], + "node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="], + + "node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="], + "node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="], "node-gyp-build-optional-packages": ["node-gyp-build-optional-packages@5.1.1", "", { "dependencies": { "detect-libc": "^2.0.1" }, "bin": { "node-gyp-build-optional-packages": "bin.js", "node-gyp-build-optional-packages-test": "build-test.js", "node-gyp-build-optional-packages-optional": "optional.js" } }, "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw=="], @@ -1147,8 +1188,6 @@ "pg": ["pg@8.18.0", "", { "dependencies": { "pg-connection-string": "^2.11.0", "pg-pool": "^3.11.0", "pg-protocol": "^1.11.0", "pg-types": "2.2.0", "pgpass": "1.0.5" }, "optionalDependencies": { "pg-cloudflare": "^1.3.0" }, "peerDependencies": { "pg-native": ">=3.0.1" }, "optionalPeers": ["pg-native"] }, "sha512-xqrUDL1b9MbkydY/s+VZ6v+xiMUmOUk7SS9d/1kpyQxoJ6U9AO1oIJyUWVZojbfe5Cc/oluutcgFG4L9RDP1iQ=="], - "pg-boss": ["pg-boss@11.0.7", "", { "dependencies": { "cron-parser": "^5.4.0", "pg": "^8.16.3", "serialize-error": "^8.1.0" } }, "sha512-UaCAE4u1bHBwV3yDl8q3qSPKglyRCz/e9wKSbrYsyqzxIkCQ3rNeUYHqX4DAPLxW96RCMifxtMOvq093IZNVug=="], - "pg-cloudflare": ["pg-cloudflare@1.3.0", "", {}, "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ=="], "pg-connection-string": ["pg-connection-string@2.11.0", "", {}, "sha512-kecgoJwhOpxYU21rZjULrmrBJ698U2RxXofKVzOn5UDj61BPj/qMb7diYUR1nLScCDbrztQFl1TaQZT0t1EtzQ=="], @@ -1185,6 +1224,8 @@ "postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "^4.0.0" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="], + "promise-limit": ["promise-limit@2.7.0", "", {}, "sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw=="], + "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], "qs": ["qs@6.14.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q=="], @@ -1261,8 +1302,6 @@ "send": ["send@0.19.2", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "~0.5.2", "http-errors": "~2.0.1", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "~2.4.1", "range-parser": "~1.2.1", "statuses": "~2.0.2" } }, "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg=="], - "serialize-error": ["serialize-error@8.1.0", "", { "dependencies": { "type-fest": "^0.20.2" } }, "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ=="], - "serve-static": ["serve-static@1.16.3", "", { "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "~0.19.1" } }, "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA=="], "set-cookie-parser": ["set-cookie-parser@2.7.2", "", {}, "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw=="], @@ -1347,9 +1386,11 @@ "token-types": ["token-types@6.1.2", "", { "dependencies": { "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww=="], + "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "type-fest": ["type-fest@0.20.2", "", {}, "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="], + "type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], "type-is": ["type-is@1.6.18", "", { "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="], @@ -1395,8 +1436,14 @@ "wcwidth": ["wcwidth@1.0.1", "", { "dependencies": { "defaults": "^1.0.3" } }, "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg=="], + "web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="], + + "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], + "webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="], + "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], "widest-line": ["widest-line@3.1.0", "", { "dependencies": { "string-width": "^4.0.0" } }, "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg=="], @@ -1407,6 +1454,8 @@ "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + "ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="], + "wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="], "xdg-app-paths": ["xdg-app-paths@5.1.0", "", { "dependencies": { "xdg-portable": "^7.0.0" } }, "sha512-RAQ3WkPf4KTU1A8RtFx3gWywzVKe00tfOPFfl2NDGqbIFENQO4kqAJp7mhQjNj/33W5x5hiWWUdyfPq/5SU3QA=="], @@ -1419,7 +1468,7 @@ "yocto-queue": ["yocto-queue@1.2.2", "", {}, "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ=="], - "zod": ["zod@4.1.11", "", {}, "sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg=="], + "zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], "@aws-crypto/sha256-browser/@aws-sdk/types": ["@aws-sdk/types@3.973.3", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-tma6D8/xHZHJEUqmr6ksZjZ0onyIUqKDQLyp50ttZJmS0IwFYzxBgp5CxFvpYAnah52V3UtgrqGA6E83gtT7NQ=="], @@ -1531,8 +1580,6 @@ "@aws-sdk/xml-builder/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="], - "@better-auth/core/zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], - "@esbuild-kit/core-utils/esbuild": ["esbuild@0.18.20", "", { "optionalDependencies": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", "@esbuild/android-x64": "0.18.20", "@esbuild/darwin-arm64": "0.18.20", "@esbuild/darwin-x64": "0.18.20", "@esbuild/freebsd-arm64": "0.18.20", "@esbuild/freebsd-x64": "0.18.20", "@esbuild/linux-arm": "0.18.20", "@esbuild/linux-arm64": "0.18.20", "@esbuild/linux-ia32": "0.18.20", "@esbuild/linux-loong64": "0.18.20", "@esbuild/linux-mips64el": "0.18.20", "@esbuild/linux-ppc64": "0.18.20", "@esbuild/linux-riscv64": "0.18.20", "@esbuild/linux-s390x": "0.18.20", "@esbuild/linux-x64": "0.18.20", "@esbuild/netbsd-x64": "0.18.20", "@esbuild/openbsd-x64": "0.18.20", "@esbuild/sunos-x64": "0.18.20", "@esbuild/win32-arm64": "0.18.20", "@esbuild/win32-ia32": "0.18.20", "@esbuild/win32-x64": "0.18.20" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA=="], "@nuxt/kit/tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], @@ -1607,23 +1654,33 @@ "@vercel/cli-auth/open": ["open@8.4.0", "", { "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" } }, "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q=="], - "@workflow/builders/enhanced-resolve": ["enhanced-resolve@5.18.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ=="], + "@vercel/cli-auth/zod": ["zod@4.1.11", "", {}, "sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg=="], - "@workflow/cli/dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="], + "@vercel/functions/@vercel/oidc": ["@vercel/oidc@3.2.0", "", {}, "sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug=="], + + "@vercel/queue/@vercel/oidc": ["@vercel/oidc@3.2.0", "", {}, "sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug=="], + + "@vercel/queue/mixpart": ["mixpart@0.0.5-alpha.1", "", {}, "sha512-2ZfG/NO2SVE9HLk1/W+yOrIOA0d674ljZExLdievZQpYjbJYQjIdye8vNMR63yF7nN/NbO9q8mp16JUEYBCilg=="], + + "@workflow/builders/enhanced-resolve": ["enhanced-resolve@5.18.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ=="], "@workflow/cli/enhanced-resolve": ["enhanced-resolve@5.18.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ=="], - "@workflow/cli/mixpart": ["mixpart@0.0.4", "", {}, "sha512-RAoaOSXnMLrfUfmFbNynRYjeMru/bhgAYRy/GQVI8gmRq7vm9V9c2gGVYnYoQ008X6YTmRIu5b0397U7vb0bIA=="], + "@workflow/cli/zod": ["zod@4.1.11", "", {}, "sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg=="], "@workflow/core/@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="], "@workflow/core/nanoid": ["nanoid@5.1.6", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg=="], + "@workflow/core/zod": ["zod@4.1.11", "", {}, "sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg=="], + "@workflow/next/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], - "@workflow/world-postgres/drizzle-orm": ["drizzle-orm@0.44.7", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-quIpnYznjU9lHshEOAYLoZ9s3jweleHlZIAWR/jX9gAWNg/JhQ1wj0KGRf7/Zm+obRrYd9GjPVJg790QY9N5AQ=="], + "@workflow/world/zod": ["zod@4.1.11", "", {}, "sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg=="], - "@workflow/world-vercel/@vercel/oidc": ["@vercel/oidc@3.0.5", "", {}, "sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw=="], + "@workflow/world-local/zod": ["zod@4.1.11", "", {}, "sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg=="], + + "@workflow/world-vercel/zod": ["zod@4.1.11", "", {}, "sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg=="], "@xhmikosr/archive-type/file-type": ["file-type@20.5.0", "", { "dependencies": { "@tokenizer/inflate": "^0.2.6", "strtok3": "^10.2.0", "token-types": "^6.0.0", "uint8array-extras": "^1.4.0" } }, "sha512-BfHZtG/l9iMm4Ecianu7P8HRD2tBHLtjXinm4X62XBOYzi7CYA7jyqfJzOvXHqzVrVPYqBo2/GvbARMaaJkKVg=="], @@ -1641,14 +1698,10 @@ "ansi-escapes/type-fest": ["type-fest@0.21.3", "", {}, "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="], - "better-auth/zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], - "body-parser/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], "boxen/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], - "boxen/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], - "boxen/widest-line": ["widest-line@5.0.0", "", { "dependencies": { "string-width": "^7.0.0" } }, "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA=="], "boxen/wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], @@ -1659,6 +1712,8 @@ "c12/exsolve": ["exsolve@1.0.8", "", {}, "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA=="], + "cross-fetch/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], + "decompress-response/mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], "execa/onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], @@ -1679,6 +1734,8 @@ "is-inside-container/is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="], + "lightningcss/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + "log-symbols/is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="], "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], @@ -1687,6 +1744,8 @@ "next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="], + "node-gyp-build-optional-packages/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + "nypm/citty": ["citty@0.2.1", "", {}, "sha512-kEV95lFBhQgtogAPlQfJJ0WGVSokvLr/UEoFPiKKOXF7pl98HfUVUD0ejsuTCld/9xH9vogSywZ5KqHzXrZpqg=="], "ora/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], @@ -1695,6 +1754,8 @@ "send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + "sharp/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + "source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], "string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], diff --git a/docker-compose.yml b/docker-compose.yml index e2348b3..44edb57 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,22 +13,21 @@ services: PORT: 3000 HOSTNAME: 0.0.0.0 NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-} - DATABASE_URL: ${DATABASE_URL:-postgres://postgres:postgres@postgres:5432/fiscal_clone} + DATABASE_URL: ${DATABASE_URL:-file:/app/data/fiscal.sqlite} BETTER_AUTH_SECRET: ${BETTER_AUTH_SECRET:-} - BETTER_AUTH_BASE_URL: ${BETTER_AUTH_BASE_URL:-} + BETTER_AUTH_BASE_URL: ${BETTER_AUTH_BASE_URL:-https://fiscal.b11studio.xyz} BETTER_AUTH_ADMIN_USER_IDS: ${BETTER_AUTH_ADMIN_USER_IDS:-} - BETTER_AUTH_TRUSTED_ORIGINS: ${BETTER_AUTH_TRUSTED_ORIGINS:-} + BETTER_AUTH_TRUSTED_ORIGINS: ${BETTER_AUTH_TRUSTED_ORIGINS:-https://fiscal.b11studio.xyz} OPENCLAW_BASE_URL: ${OPENCLAW_BASE_URL:-} OPENCLAW_API_KEY: ${OPENCLAW_API_KEY:-} OPENCLAW_MODEL: ${OPENCLAW_MODEL:-zeroclaw} SEC_USER_AGENT: ${SEC_USER_AGENT:-Fiscal Clone } - WORKFLOW_TARGET_WORLD: ${WORKFLOW_TARGET_WORLD:-@workflow/world-postgres} - WORKFLOW_POSTGRES_URL: ${WORKFLOW_POSTGRES_URL:-postgres://postgres:postgres@postgres:5432/fiscal_clone} - WORKFLOW_POSTGRES_JOB_PREFIX: ${WORKFLOW_POSTGRES_JOB_PREFIX:-fiscal_clone} - WORKFLOW_POSTGRES_WORKER_CONCURRENCY: ${WORKFLOW_POSTGRES_WORKER_CONCURRENCY:-10} - depends_on: - postgres: - condition: service_healthy + WORKFLOW_TARGET_WORLD: ${WORKFLOW_TARGET_WORLD:-local} + WORKFLOW_LOCAL_DATA_DIR: ${WORKFLOW_LOCAL_DATA_DIR:-/app/.workflow-data} + WORKFLOW_LOCAL_QUEUE_CONCURRENCY: ${WORKFLOW_LOCAL_QUEUE_CONCURRENCY:-100} + volumes: + - fiscal_sqlite_data:/app/data + - fiscal_workflow_data:/app/.workflow-data healthcheck: test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1:3000/api/health || exit 1"] interval: 30s @@ -36,20 +35,7 @@ services: retries: 3 expose: - "3000" - postgres: - image: postgres:16-alpine - restart: unless-stopped - environment: - POSTGRES_DB: ${POSTGRES_DB:-fiscal_clone} - POSTGRES_USER: ${POSTGRES_USER:-postgres} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres} - volumes: - - postgres_data:/var/lib/postgresql/data - healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-fiscal_clone}"] - interval: 10s - timeout: 5s - retries: 5 volumes: - postgres_data: + fiscal_sqlite_data: + fiscal_workflow_data: diff --git a/drizzle.config.ts b/drizzle.config.ts index 42be20f..b9cbc51 100644 --- a/drizzle.config.ts +++ b/drizzle.config.ts @@ -1,13 +1,9 @@ -const databaseUrl = process.env.DATABASE_URL?.trim(); - -if (!databaseUrl) { - throw new Error('DATABASE_URL is required to run Drizzle migrations.'); -} +const databaseUrl = process.env.DATABASE_URL?.trim() || 'file:data/fiscal.sqlite'; export default { schema: './lib/server/db/schema.ts', out: './drizzle', - dialect: 'postgresql', + dialect: 'sqlite', dbCredentials: { url: databaseUrl }, diff --git a/drizzle/0000_cold_silver_centurion.sql b/drizzle/0000_cold_silver_centurion.sql new file mode 100644 index 0000000..461d05c --- /dev/null +++ b/drizzle/0000_cold_silver_centurion.sql @@ -0,0 +1,190 @@ +CREATE TABLE `account` ( + `id` text PRIMARY KEY NOT NULL, + `accountId` text NOT NULL, + `providerId` text NOT NULL, + `userId` text NOT NULL, + `accessToken` text, + `refreshToken` text, + `idToken` text, + `accessTokenExpiresAt` integer, + `refreshTokenExpiresAt` integer, + `scope` text, + `password` text, + `createdAt` integer NOT NULL, + `updatedAt` integer NOT NULL, + FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE INDEX `account_userId_idx` ON `account` (`userId`);--> statement-breakpoint +CREATE TABLE `filing` ( + `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL, + `ticker` text NOT NULL, + `filing_type` text NOT NULL, + `filing_date` text NOT NULL, + `accession_number` text NOT NULL, + `cik` text NOT NULL, + `company_name` text NOT NULL, + `filing_url` text, + `submission_url` text, + `primary_document` text, + `metrics` text, + `analysis` text, + `created_at` text NOT NULL, + `updated_at` text NOT NULL +); +--> statement-breakpoint +CREATE UNIQUE INDEX `filing_accession_uidx` ON `filing` (`accession_number`);--> statement-breakpoint +CREATE INDEX `filing_ticker_date_idx` ON `filing` (`ticker`,`filing_date`);--> statement-breakpoint +CREATE INDEX `filing_date_idx` ON `filing` (`filing_date`);--> statement-breakpoint +CREATE TABLE `filing_link` ( + `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL, + `filing_id` integer NOT NULL, + `link_type` text NOT NULL, + `url` text NOT NULL, + `source` text DEFAULT 'sec' NOT NULL, + `created_at` text NOT NULL, + FOREIGN KEY (`filing_id`) REFERENCES `filing`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE UNIQUE INDEX `filing_link_unique_uidx` ON `filing_link` (`filing_id`,`url`);--> statement-breakpoint +CREATE INDEX `filing_link_filing_idx` ON `filing_link` (`filing_id`);--> statement-breakpoint +CREATE TABLE `holding` ( + `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL, + `user_id` text NOT NULL, + `ticker` text NOT NULL, + `shares` numeric NOT NULL, + `avg_cost` numeric NOT NULL, + `current_price` numeric, + `market_value` numeric NOT NULL, + `gain_loss` numeric NOT NULL, + `gain_loss_pct` numeric NOT NULL, + `last_price_at` text, + `created_at` text NOT NULL, + `updated_at` text NOT NULL, + FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE UNIQUE INDEX `holding_user_ticker_uidx` ON `holding` (`user_id`,`ticker`);--> statement-breakpoint +CREATE INDEX `holding_user_idx` ON `holding` (`user_id`);--> statement-breakpoint +CREATE TABLE `invitation` ( + `id` text PRIMARY KEY NOT NULL, + `organizationId` text NOT NULL, + `email` text NOT NULL, + `role` text, + `status` text DEFAULT 'pending' NOT NULL, + `expiresAt` integer NOT NULL, + `createdAt` integer NOT NULL, + `inviterId` text NOT NULL, + FOREIGN KEY (`organizationId`) REFERENCES `organization`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`inviterId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE INDEX `invitation_organizationId_idx` ON `invitation` (`organizationId`);--> statement-breakpoint +CREATE INDEX `invitation_email_idx` ON `invitation` (`email`);--> statement-breakpoint +CREATE TABLE `member` ( + `id` text PRIMARY KEY NOT NULL, + `organizationId` text NOT NULL, + `userId` text NOT NULL, + `role` text DEFAULT 'member' NOT NULL, + `createdAt` integer NOT NULL, + FOREIGN KEY (`organizationId`) REFERENCES `organization`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE INDEX `member_organizationId_idx` ON `member` (`organizationId`);--> statement-breakpoint +CREATE INDEX `member_userId_idx` ON `member` (`userId`);--> statement-breakpoint +CREATE TABLE `organization` ( + `id` text PRIMARY KEY NOT NULL, + `name` text NOT NULL, + `slug` text NOT NULL, + `logo` text, + `createdAt` integer NOT NULL, + `metadata` text +); +--> statement-breakpoint +CREATE UNIQUE INDEX `organization_slug_uidx` ON `organization` (`slug`);--> statement-breakpoint +CREATE TABLE `portfolio_insight` ( + `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL, + `user_id` text NOT NULL, + `provider` text NOT NULL, + `model` text NOT NULL, + `content` text NOT NULL, + `created_at` text NOT NULL, + FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE INDEX `insight_user_created_idx` ON `portfolio_insight` (`user_id`,`created_at`);--> statement-breakpoint +CREATE TABLE `session` ( + `id` text PRIMARY KEY NOT NULL, + `expiresAt` integer NOT NULL, + `token` text NOT NULL, + `createdAt` integer NOT NULL, + `updatedAt` integer NOT NULL, + `ipAddress` text, + `userAgent` text, + `userId` text NOT NULL, + `impersonatedBy` text, + `activeOrganizationId` text, + FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE UNIQUE INDEX `session_token_uidx` ON `session` (`token`);--> statement-breakpoint +CREATE INDEX `session_userId_idx` ON `session` (`userId`);--> statement-breakpoint +CREATE TABLE `task_run` ( + `id` text PRIMARY KEY NOT NULL, + `user_id` text NOT NULL, + `task_type` text NOT NULL, + `status` text NOT NULL, + `priority` integer NOT NULL, + `payload` text NOT NULL, + `result` text, + `error` text, + `attempts` integer NOT NULL, + `max_attempts` integer NOT NULL, + `workflow_run_id` text, + `created_at` text NOT NULL, + `updated_at` text NOT NULL, + `finished_at` text, + FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE INDEX `task_user_created_idx` ON `task_run` (`user_id`,`created_at`);--> statement-breakpoint +CREATE INDEX `task_status_idx` ON `task_run` (`status`);--> statement-breakpoint +CREATE UNIQUE INDEX `task_workflow_run_uidx` ON `task_run` (`workflow_run_id`);--> statement-breakpoint +CREATE TABLE `user` ( + `id` text PRIMARY KEY NOT NULL, + `name` text NOT NULL, + `email` text NOT NULL, + `emailVerified` integer DEFAULT false NOT NULL, + `image` text, + `createdAt` integer NOT NULL, + `updatedAt` integer NOT NULL, + `role` text, + `banned` integer DEFAULT false, + `banReason` text, + `banExpires` integer +); +--> statement-breakpoint +CREATE UNIQUE INDEX `user_email_uidx` ON `user` (`email`);--> statement-breakpoint +CREATE TABLE `verification` ( + `id` text PRIMARY KEY NOT NULL, + `identifier` text NOT NULL, + `value` text NOT NULL, + `expiresAt` integer NOT NULL, + `createdAt` integer NOT NULL, + `updatedAt` integer NOT NULL +); +--> statement-breakpoint +CREATE INDEX `verification_identifier_idx` ON `verification` (`identifier`);--> statement-breakpoint +CREATE TABLE `watchlist_item` ( + `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL, + `user_id` text NOT NULL, + `ticker` text NOT NULL, + `company_name` text NOT NULL, + `sector` text, + `created_at` text NOT NULL, + FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE UNIQUE INDEX `watchlist_user_ticker_uidx` ON `watchlist_item` (`user_id`,`ticker`);--> statement-breakpoint +CREATE INDEX `watchlist_user_created_idx` ON `watchlist_item` (`user_id`,`created_at`); \ No newline at end of file diff --git a/drizzle/0000_tense_centennial.sql b/drizzle/0000_tense_centennial.sql deleted file mode 100644 index 9d3e2f2..0000000 --- a/drizzle/0000_tense_centennial.sql +++ /dev/null @@ -1,199 +0,0 @@ -CREATE TABLE IF NOT EXISTS "account" ( - "id" text PRIMARY KEY NOT NULL, - "accountId" text NOT NULL, - "providerId" text NOT NULL, - "userId" text NOT NULL, - "accessToken" text, - "refreshToken" text, - "idToken" text, - "accessTokenExpiresAt" timestamp with time zone, - "refreshTokenExpiresAt" timestamp with time zone, - "scope" text, - "password" text, - "createdAt" timestamp with time zone NOT NULL, - "updatedAt" timestamp with time zone NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "invitation" ( - "id" text PRIMARY KEY NOT NULL, - "organizationId" text NOT NULL, - "email" text NOT NULL, - "role" text, - "status" text DEFAULT 'pending' NOT NULL, - "expiresAt" timestamp with time zone NOT NULL, - "createdAt" timestamp with time zone NOT NULL, - "inviterId" text NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "member" ( - "id" text PRIMARY KEY NOT NULL, - "organizationId" text NOT NULL, - "userId" text NOT NULL, - "role" text DEFAULT 'member' NOT NULL, - "createdAt" timestamp with time zone NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "organization" ( - "id" text PRIMARY KEY NOT NULL, - "name" text NOT NULL, - "slug" text NOT NULL, - "logo" text, - "createdAt" timestamp with time zone NOT NULL, - "metadata" text -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "session" ( - "id" text PRIMARY KEY NOT NULL, - "expiresAt" timestamp with time zone NOT NULL, - "token" text NOT NULL, - "createdAt" timestamp with time zone NOT NULL, - "updatedAt" timestamp with time zone NOT NULL, - "ipAddress" text, - "userAgent" text, - "userId" text NOT NULL, - "impersonatedBy" text, - "activeOrganizationId" text -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "user" ( - "id" text PRIMARY KEY NOT NULL, - "name" text NOT NULL, - "email" text NOT NULL, - "emailVerified" boolean DEFAULT false NOT NULL, - "image" text, - "createdAt" timestamp with time zone NOT NULL, - "updatedAt" timestamp with time zone NOT NULL, - "role" text, - "banned" boolean DEFAULT false, - "banReason" text, - "banExpires" timestamp with time zone -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "verification" ( - "id" text PRIMARY KEY NOT NULL, - "identifier" text NOT NULL, - "value" text NOT NULL, - "expiresAt" timestamp with time zone NOT NULL, - "createdAt" timestamp with time zone NOT NULL, - "updatedAt" timestamp with time zone NOT NULL -); ---> statement-breakpoint -DO $$ -DECLARE - m record; -BEGIN - FOR m IN ( - SELECT * FROM ( - VALUES - ('user', 'email_verified', 'emailVerified'), - ('user', 'emailverified', 'emailVerified'), - ('user', 'created_at', 'createdAt'), - ('user', 'createdat', 'createdAt'), - ('user', 'updated_at', 'updatedAt'), - ('user', 'updatedat', 'updatedAt'), - ('user', 'ban_reason', 'banReason'), - ('user', 'banreason', 'banReason'), - ('user', 'ban_expires', 'banExpires'), - ('user', 'banexpires', 'banExpires'), - ('organization', 'created_at', 'createdAt'), - ('organization', 'createdat', 'createdAt'), - ('session', 'expires_at', 'expiresAt'), - ('session', 'expiresat', 'expiresAt'), - ('session', 'created_at', 'createdAt'), - ('session', 'createdat', 'createdAt'), - ('session', 'updated_at', 'updatedAt'), - ('session', 'updatedat', 'updatedAt'), - ('session', 'ip_address', 'ipAddress'), - ('session', 'ipaddress', 'ipAddress'), - ('session', 'user_agent', 'userAgent'), - ('session', 'useragent', 'userAgent'), - ('session', 'user_id', 'userId'), - ('session', 'userid', 'userId'), - ('session', 'impersonated_by', 'impersonatedBy'), - ('session', 'impersonatedby', 'impersonatedBy'), - ('session', 'active_organization_id', 'activeOrganizationId'), - ('session', 'activeorganizationid', 'activeOrganizationId'), - ('account', 'account_id', 'accountId'), - ('account', 'accountid', 'accountId'), - ('account', 'provider_id', 'providerId'), - ('account', 'providerid', 'providerId'), - ('account', 'user_id', 'userId'), - ('account', 'userid', 'userId'), - ('account', 'access_token', 'accessToken'), - ('account', 'accesstoken', 'accessToken'), - ('account', 'refresh_token', 'refreshToken'), - ('account', 'refreshtoken', 'refreshToken'), - ('account', 'id_token', 'idToken'), - ('account', 'idtoken', 'idToken'), - ('account', 'access_token_expires_at', 'accessTokenExpiresAt'), - ('account', 'accesstokenexpiresat', 'accessTokenExpiresAt'), - ('account', 'refresh_token_expires_at', 'refreshTokenExpiresAt'), - ('account', 'refreshtokenexpiresat', 'refreshTokenExpiresAt'), - ('account', 'created_at', 'createdAt'), - ('account', 'createdat', 'createdAt'), - ('account', 'updated_at', 'updatedAt'), - ('account', 'updatedat', 'updatedAt'), - ('verification', 'expires_at', 'expiresAt'), - ('verification', 'expiresat', 'expiresAt'), - ('verification', 'created_at', 'createdAt'), - ('verification', 'createdat', 'createdAt'), - ('verification', 'updated_at', 'updatedAt'), - ('verification', 'updatedat', 'updatedAt'), - ('member', 'organization_id', 'organizationId'), - ('member', 'organizationid', 'organizationId'), - ('member', 'user_id', 'userId'), - ('member', 'userid', 'userId'), - ('member', 'created_at', 'createdAt'), - ('member', 'createdat', 'createdAt'), - ('invitation', 'organization_id', 'organizationId'), - ('invitation', 'organizationid', 'organizationId'), - ('invitation', 'expires_at', 'expiresAt'), - ('invitation', 'expiresat', 'expiresAt'), - ('invitation', 'created_at', 'createdAt'), - ('invitation', 'createdat', 'createdAt'), - ('invitation', 'inviter_id', 'inviterId'), - ('invitation', 'inviterid', 'inviterId') - ) AS rename_map(table_name, old_column, new_column) - ) - LOOP - IF EXISTS ( - SELECT 1 - FROM information_schema.columns - WHERE table_schema = 'public' - AND table_name = m.table_name - AND column_name = m.old_column - ) - AND NOT EXISTS ( - SELECT 1 - FROM information_schema.columns - WHERE table_schema = 'public' - AND table_name = m.table_name - AND column_name = m.new_column - ) THEN - EXECUTE format( - 'ALTER TABLE %I.%I RENAME COLUMN %I TO %I', - 'public', - m.table_name, - m.old_column, - m.new_column - ); - END IF; - END LOOP; -END $$; ---> statement-breakpoint -DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'account_userId_user_id_fk') THEN ALTER TABLE "account" ADD CONSTRAINT "account_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action; END IF; END $$;--> statement-breakpoint -DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'invitation_organizationId_organization_id_fk') THEN ALTER TABLE "invitation" ADD CONSTRAINT "invitation_organizationId_organization_id_fk" FOREIGN KEY ("organizationId") REFERENCES "public"."organization"("id") ON DELETE cascade ON UPDATE no action; END IF; END $$;--> statement-breakpoint -DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'invitation_inviterId_user_id_fk') THEN ALTER TABLE "invitation" ADD CONSTRAINT "invitation_inviterId_user_id_fk" FOREIGN KEY ("inviterId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action; END IF; END $$;--> statement-breakpoint -DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'member_organizationId_organization_id_fk') THEN ALTER TABLE "member" ADD CONSTRAINT "member_organizationId_organization_id_fk" FOREIGN KEY ("organizationId") REFERENCES "public"."organization"("id") ON DELETE cascade ON UPDATE no action; END IF; END $$;--> statement-breakpoint -DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'member_userId_user_id_fk') THEN ALTER TABLE "member" ADD CONSTRAINT "member_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action; END IF; END $$;--> statement-breakpoint -DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'session_userId_user_id_fk') THEN ALTER TABLE "session" ADD CONSTRAINT "session_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action; END IF; END $$;--> statement-breakpoint -CREATE INDEX IF NOT EXISTS "account_userId_idx" ON "account" USING btree ("userId");--> statement-breakpoint -CREATE INDEX IF NOT EXISTS "invitation_organizationId_idx" ON "invitation" USING btree ("organizationId");--> statement-breakpoint -CREATE INDEX IF NOT EXISTS "invitation_email_idx" ON "invitation" USING btree ("email");--> statement-breakpoint -CREATE INDEX IF NOT EXISTS "member_organizationId_idx" ON "member" USING btree ("organizationId");--> statement-breakpoint -CREATE INDEX IF NOT EXISTS "member_userId_idx" ON "member" USING btree ("userId");--> statement-breakpoint -CREATE UNIQUE INDEX IF NOT EXISTS "organization_slug_uidx" ON "organization" USING btree ("slug");--> statement-breakpoint -CREATE UNIQUE INDEX IF NOT EXISTS "session_token_uidx" ON "session" USING btree ("token");--> statement-breakpoint -CREATE INDEX IF NOT EXISTS "session_userId_idx" ON "session" USING btree ("userId");--> statement-breakpoint -CREATE UNIQUE INDEX IF NOT EXISTS "user_email_uidx" ON "user" USING btree ("email");--> statement-breakpoint -CREATE INDEX IF NOT EXISTS "verification_identifier_idx" ON "verification" USING btree ("identifier"); diff --git a/drizzle/0001_boring_toad.sql b/drizzle/0001_boring_toad.sql deleted file mode 100644 index c900ef1..0000000 --- a/drizzle/0001_boring_toad.sql +++ /dev/null @@ -1,94 +0,0 @@ -CREATE TABLE "filing" ( - "id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "filing_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1), - "ticker" text NOT NULL, - "filing_type" text NOT NULL, - "filing_date" text NOT NULL, - "accession_number" text NOT NULL, - "cik" text NOT NULL, - "company_name" text NOT NULL, - "filing_url" text, - "submission_url" text, - "primary_document" text, - "metrics" jsonb, - "analysis" jsonb, - "created_at" timestamp with time zone NOT NULL, - "updated_at" timestamp with time zone NOT NULL -); ---> statement-breakpoint -CREATE TABLE "filing_link" ( - "id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "filing_link_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1), - "filing_id" integer NOT NULL, - "link_type" text NOT NULL, - "url" text NOT NULL, - "source" text DEFAULT 'sec' NOT NULL, - "created_at" timestamp with time zone NOT NULL -); ---> statement-breakpoint -CREATE TABLE "holding" ( - "id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "holding_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1), - "user_id" text NOT NULL, - "ticker" text NOT NULL, - "shares" numeric(30, 6) NOT NULL, - "avg_cost" numeric(30, 6) NOT NULL, - "current_price" numeric(30, 6), - "market_value" numeric(30, 2) NOT NULL, - "gain_loss" numeric(30, 2) NOT NULL, - "gain_loss_pct" numeric(30, 2) NOT NULL, - "last_price_at" timestamp with time zone, - "created_at" timestamp with time zone NOT NULL, - "updated_at" timestamp with time zone NOT NULL -); ---> statement-breakpoint -CREATE TABLE "portfolio_insight" ( - "id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "portfolio_insight_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1), - "user_id" text NOT NULL, - "provider" text NOT NULL, - "model" text NOT NULL, - "content" text NOT NULL, - "created_at" timestamp with time zone NOT NULL -); ---> statement-breakpoint -CREATE TABLE "task_run" ( - "id" text PRIMARY KEY NOT NULL, - "user_id" text NOT NULL, - "task_type" text NOT NULL, - "status" text NOT NULL, - "priority" integer NOT NULL, - "payload" jsonb NOT NULL, - "result" jsonb, - "error" text, - "attempts" integer NOT NULL, - "max_attempts" integer NOT NULL, - "workflow_run_id" text, - "created_at" timestamp with time zone NOT NULL, - "updated_at" timestamp with time zone NOT NULL, - "finished_at" timestamp with time zone -); ---> statement-breakpoint -CREATE TABLE "watchlist_item" ( - "id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "watchlist_item_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1), - "user_id" text NOT NULL, - "ticker" text NOT NULL, - "company_name" text NOT NULL, - "sector" text, - "created_at" timestamp with time zone NOT NULL -); ---> statement-breakpoint -ALTER TABLE "filing_link" ADD CONSTRAINT "filing_link_filing_id_filing_id_fk" FOREIGN KEY ("filing_id") REFERENCES "public"."filing"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint -ALTER TABLE "holding" ADD CONSTRAINT "holding_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint -ALTER TABLE "portfolio_insight" ADD CONSTRAINT "portfolio_insight_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint -ALTER TABLE "task_run" ADD CONSTRAINT "task_run_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint -ALTER TABLE "watchlist_item" ADD CONSTRAINT "watchlist_item_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint -CREATE UNIQUE INDEX "filing_accession_uidx" ON "filing" USING btree ("accession_number");--> statement-breakpoint -CREATE INDEX "filing_ticker_date_idx" ON "filing" USING btree ("ticker","filing_date");--> statement-breakpoint -CREATE INDEX "filing_date_idx" ON "filing" USING btree ("filing_date");--> statement-breakpoint -CREATE UNIQUE INDEX "filing_link_unique_uidx" ON "filing_link" USING btree ("filing_id","url");--> statement-breakpoint -CREATE INDEX "filing_link_filing_idx" ON "filing_link" USING btree ("filing_id");--> statement-breakpoint -CREATE UNIQUE INDEX "holding_user_ticker_uidx" ON "holding" USING btree ("user_id","ticker");--> statement-breakpoint -CREATE INDEX "holding_user_idx" ON "holding" USING btree ("user_id");--> statement-breakpoint -CREATE INDEX "insight_user_created_idx" ON "portfolio_insight" USING btree ("user_id","created_at");--> statement-breakpoint -CREATE INDEX "task_user_created_idx" ON "task_run" USING btree ("user_id","created_at");--> statement-breakpoint -CREATE INDEX "task_status_idx" ON "task_run" USING btree ("status");--> statement-breakpoint -CREATE UNIQUE INDEX "task_workflow_run_uidx" ON "task_run" USING btree ("workflow_run_id");--> statement-breakpoint -CREATE UNIQUE INDEX "watchlist_user_ticker_uidx" ON "watchlist_item" USING btree ("user_id","ticker");--> statement-breakpoint -CREATE INDEX "watchlist_user_created_idx" ON "watchlist_item" USING btree ("user_id","created_at"); \ No newline at end of file diff --git a/drizzle/meta/0000_snapshot.json b/drizzle/meta/0000_snapshot.json index 790b8e0..4fdaa71 100644 --- a/drizzle/meta/0000_snapshot.json +++ b/drizzle/meta/0000_snapshot.json @@ -1,107 +1,111 @@ { - "id": "c490542d-7f2f-49f2-8a4f-813dd6c2e9c5", + "version": "6", + "dialect": "sqlite", + "id": "cf403080-e012-41c0-93a2-52333bb44df1", "prevId": "00000000-0000-0000-0000-000000000000", - "version": "7", - "dialect": "postgresql", "tables": { - "public.account": { + "account": { "name": "account", - "schema": "", "columns": { "id": { "name": "id", "type": "text", "primaryKey": true, - "notNull": true + "notNull": true, + "autoincrement": false }, "accountId": { "name": "accountId", "type": "text", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "providerId": { "name": "providerId", "type": "text", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "userId": { "name": "userId", "type": "text", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "accessToken": { "name": "accessToken", "type": "text", "primaryKey": false, - "notNull": false + "notNull": false, + "autoincrement": false }, "refreshToken": { "name": "refreshToken", "type": "text", "primaryKey": false, - "notNull": false + "notNull": false, + "autoincrement": false }, "idToken": { "name": "idToken", "type": "text", "primaryKey": false, - "notNull": false + "notNull": false, + "autoincrement": false }, "accessTokenExpiresAt": { "name": "accessTokenExpiresAt", - "type": "timestamp with time zone", + "type": "integer", "primaryKey": false, - "notNull": false + "notNull": false, + "autoincrement": false }, "refreshTokenExpiresAt": { "name": "refreshTokenExpiresAt", - "type": "timestamp with time zone", + "type": "integer", "primaryKey": false, - "notNull": false + "notNull": false, + "autoincrement": false }, "scope": { "name": "scope", "type": "text", "primaryKey": false, - "notNull": false + "notNull": false, + "autoincrement": false }, "password": { "name": "password", "type": "text", "primaryKey": false, - "notNull": false + "notNull": false, + "autoincrement": false }, "createdAt": { "name": "createdAt", - "type": "timestamp with time zone", + "type": "integer", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "updatedAt": { "name": "updatedAt", - "type": "timestamp with time zone", + "type": "integer", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false } }, "indexes": { "account_userId_idx": { "name": "account_userId_idx", "columns": [ - { - "expression": "userId", - "isExpression": false, - "asc": true, - "nulls": "last" - } + "userId" ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} + "isUnique": false } }, "foreignKeys": { @@ -121,94 +125,421 @@ }, "compositePrimaryKeys": {}, "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false + "checkConstraints": {} }, - "public.invitation": { + "filing": { + "name": "filing", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "ticker": { + "name": "ticker", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "filing_type": { + "name": "filing_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "filing_date": { + "name": "filing_date", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "accession_number": { + "name": "accession_number", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "cik": { + "name": "cik", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "company_name": { + "name": "company_name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "filing_url": { + "name": "filing_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "submission_url": { + "name": "submission_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "primary_document": { + "name": "primary_document", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "metrics": { + "name": "metrics", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "analysis": { + "name": "analysis", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "filing_accession_uidx": { + "name": "filing_accession_uidx", + "columns": [ + "accession_number" + ], + "isUnique": true + }, + "filing_ticker_date_idx": { + "name": "filing_ticker_date_idx", + "columns": [ + "ticker", + "filing_date" + ], + "isUnique": false + }, + "filing_date_idx": { + "name": "filing_date_idx", + "columns": [ + "filing_date" + ], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "filing_link": { + "name": "filing_link", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "filing_id": { + "name": "filing_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "link_type": { + "name": "link_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'sec'" + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "filing_link_unique_uidx": { + "name": "filing_link_unique_uidx", + "columns": [ + "filing_id", + "url" + ], + "isUnique": true + }, + "filing_link_filing_idx": { + "name": "filing_link_filing_idx", + "columns": [ + "filing_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "filing_link_filing_id_filing_id_fk": { + "name": "filing_link_filing_id_filing_id_fk", + "tableFrom": "filing_link", + "tableTo": "filing", + "columnsFrom": [ + "filing_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "holding": { + "name": "holding", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ticker": { + "name": "ticker", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "shares": { + "name": "shares", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "avg_cost": { + "name": "avg_cost", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "current_price": { + "name": "current_price", + "type": "numeric", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "market_value": { + "name": "market_value", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "gain_loss": { + "name": "gain_loss", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "gain_loss_pct": { + "name": "gain_loss_pct", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_price_at": { + "name": "last_price_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "holding_user_ticker_uidx": { + "name": "holding_user_ticker_uidx", + "columns": [ + "user_id", + "ticker" + ], + "isUnique": true + }, + "holding_user_idx": { + "name": "holding_user_idx", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "holding_user_id_user_id_fk": { + "name": "holding_user_id_user_id_fk", + "tableFrom": "holding", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "invitation": { "name": "invitation", - "schema": "", "columns": { "id": { "name": "id", "type": "text", "primaryKey": true, - "notNull": true + "notNull": true, + "autoincrement": false }, "organizationId": { "name": "organizationId", "type": "text", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "email": { "name": "email", "type": "text", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "role": { "name": "role", "type": "text", "primaryKey": false, - "notNull": false + "notNull": false, + "autoincrement": false }, "status": { "name": "status", "type": "text", "primaryKey": false, "notNull": true, + "autoincrement": false, "default": "'pending'" }, "expiresAt": { "name": "expiresAt", - "type": "timestamp with time zone", + "type": "integer", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "createdAt": { "name": "createdAt", - "type": "timestamp with time zone", + "type": "integer", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "inviterId": { "name": "inviterId", "type": "text", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false } }, "indexes": { "invitation_organizationId_idx": { "name": "invitation_organizationId_idx", "columns": [ - { - "expression": "organizationId", - "isExpression": false, - "asc": true, - "nulls": "last" - } + "organizationId" ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} + "isUnique": false }, "invitation_email_idx": { "name": "invitation_email_idx", "columns": [ - { - "expression": "email", - "isExpression": false, - "asc": true, - "nulls": "last" - } + "email" ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} + "isUnique": false } }, "foreignKeys": { @@ -241,76 +572,62 @@ }, "compositePrimaryKeys": {}, "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false + "checkConstraints": {} }, - "public.member": { + "member": { "name": "member", - "schema": "", "columns": { "id": { "name": "id", "type": "text", "primaryKey": true, - "notNull": true + "notNull": true, + "autoincrement": false }, "organizationId": { "name": "organizationId", "type": "text", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "userId": { "name": "userId", "type": "text", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "role": { "name": "role", "type": "text", "primaryKey": false, "notNull": true, + "autoincrement": false, "default": "'member'" }, "createdAt": { "name": "createdAt", - "type": "timestamp with time zone", + "type": "integer", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false } }, "indexes": { "member_organizationId_idx": { "name": "member_organizationId_idx", "columns": [ - { - "expression": "organizationId", - "isExpression": false, - "asc": true, - "nulls": "last" - } + "organizationId" ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} + "isUnique": false }, "member_userId_idx": { "name": "member_userId_idx", "columns": [ - { - "expression": "userId", - "isExpression": false, - "asc": true, - "nulls": "last" - } + "userId" ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} + "isUnique": false } }, "foreignKeys": { @@ -343,170 +660,231 @@ }, "compositePrimaryKeys": {}, "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false + "checkConstraints": {} }, - "public.organization": { + "organization": { "name": "organization", - "schema": "", "columns": { "id": { "name": "id", "type": "text", "primaryKey": true, - "notNull": true + "notNull": true, + "autoincrement": false }, "name": { "name": "name", "type": "text", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "slug": { "name": "slug", "type": "text", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "logo": { "name": "logo", "type": "text", "primaryKey": false, - "notNull": false + "notNull": false, + "autoincrement": false }, "createdAt": { "name": "createdAt", - "type": "timestamp with time zone", + "type": "integer", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "metadata": { "name": "metadata", "type": "text", "primaryKey": false, - "notNull": false + "notNull": false, + "autoincrement": false } }, "indexes": { "organization_slug_uidx": { "name": "organization_slug_uidx", "columns": [ - { - "expression": "slug", - "isExpression": false, - "asc": true, - "nulls": "last" - } + "slug" ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} + "isUnique": true } }, "foreignKeys": {}, "compositePrimaryKeys": {}, "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false + "checkConstraints": {} }, - "public.session": { + "portfolio_insight": { + "name": "portfolio_insight", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "insight_user_created_idx": { + "name": "insight_user_created_idx", + "columns": [ + "user_id", + "created_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "portfolio_insight_user_id_user_id_fk": { + "name": "portfolio_insight_user_id_user_id_fk", + "tableFrom": "portfolio_insight", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "session": { "name": "session", - "schema": "", "columns": { "id": { "name": "id", "type": "text", "primaryKey": true, - "notNull": true + "notNull": true, + "autoincrement": false }, "expiresAt": { "name": "expiresAt", - "type": "timestamp with time zone", + "type": "integer", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "token": { "name": "token", "type": "text", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "createdAt": { "name": "createdAt", - "type": "timestamp with time zone", + "type": "integer", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "updatedAt": { "name": "updatedAt", - "type": "timestamp with time zone", + "type": "integer", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "ipAddress": { "name": "ipAddress", "type": "text", "primaryKey": false, - "notNull": false + "notNull": false, + "autoincrement": false }, "userAgent": { "name": "userAgent", "type": "text", "primaryKey": false, - "notNull": false + "notNull": false, + "autoincrement": false }, "userId": { "name": "userId", "type": "text", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "impersonatedBy": { "name": "impersonatedBy", "type": "text", "primaryKey": false, - "notNull": false + "notNull": false, + "autoincrement": false }, "activeOrganizationId": { "name": "activeOrganizationId", "type": "text", "primaryKey": false, - "notNull": false + "notNull": false, + "autoincrement": false } }, "indexes": { "session_token_uidx": { "name": "session_token_uidx", "columns": [ - { - "expression": "token", - "isExpression": false, - "asc": true, - "nulls": "last" - } + "token" ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} + "isUnique": true }, "session_userId_idx": { "name": "session_userId_idx", "columns": [ - { - "expression": "userId", - "isExpression": false, - "asc": true, - "nulls": "last" - } + "userId" ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} + "isUnique": false } }, "foreignKeys": { @@ -526,182 +904,402 @@ }, "compositePrimaryKeys": {}, "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false + "checkConstraints": {} }, - "public.user": { - "name": "user", - "schema": "", + "task_run": { + "name": "task_run", "columns": { "id": { "name": "id", "type": "text", "primaryKey": true, - "notNull": true + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "task_type": { + "name": "task_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "priority": { + "name": "priority", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "payload": { + "name": "payload", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "result": { + "name": "result", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "workflow_run_id": { + "name": "workflow_run_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "finished_at": { + "name": "finished_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "task_user_created_idx": { + "name": "task_user_created_idx", + "columns": [ + "user_id", + "created_at" + ], + "isUnique": false + }, + "task_status_idx": { + "name": "task_status_idx", + "columns": [ + "status" + ], + "isUnique": false + }, + "task_workflow_run_uidx": { + "name": "task_workflow_run_uidx", + "columns": [ + "workflow_run_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "task_run_user_id_user_id_fk": { + "name": "task_run_user_id_user_id_fk", + "tableFrom": "task_run", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "user": { + "name": "user", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false }, "name": { "name": "name", "type": "text", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "email": { "name": "email", "type": "text", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "emailVerified": { "name": "emailVerified", - "type": "boolean", + "type": "integer", "primaryKey": false, "notNull": true, + "autoincrement": false, "default": false }, "image": { "name": "image", "type": "text", "primaryKey": false, - "notNull": false + "notNull": false, + "autoincrement": false }, "createdAt": { "name": "createdAt", - "type": "timestamp with time zone", + "type": "integer", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "updatedAt": { "name": "updatedAt", - "type": "timestamp with time zone", + "type": "integer", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "role": { "name": "role", "type": "text", "primaryKey": false, - "notNull": false + "notNull": false, + "autoincrement": false }, "banned": { "name": "banned", - "type": "boolean", + "type": "integer", "primaryKey": false, "notNull": false, + "autoincrement": false, "default": false }, "banReason": { "name": "banReason", "type": "text", "primaryKey": false, - "notNull": false + "notNull": false, + "autoincrement": false }, "banExpires": { "name": "banExpires", - "type": "timestamp with time zone", + "type": "integer", "primaryKey": false, - "notNull": false + "notNull": false, + "autoincrement": false } }, "indexes": { "user_email_uidx": { "name": "user_email_uidx", "columns": [ - { - "expression": "email", - "isExpression": false, - "asc": true, - "nulls": "last" - } + "email" ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} + "isUnique": true } }, "foreignKeys": {}, "compositePrimaryKeys": {}, "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false + "checkConstraints": {} }, - "public.verification": { + "verification": { "name": "verification", - "schema": "", "columns": { "id": { "name": "id", "type": "text", "primaryKey": true, - "notNull": true + "notNull": true, + "autoincrement": false }, "identifier": { "name": "identifier", "type": "text", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "value": { "name": "value", "type": "text", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "expiresAt": { "name": "expiresAt", - "type": "timestamp with time zone", + "type": "integer", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "createdAt": { "name": "createdAt", - "type": "timestamp with time zone", + "type": "integer", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false }, "updatedAt": { "name": "updatedAt", - "type": "timestamp with time zone", + "type": "integer", "primaryKey": false, - "notNull": true + "notNull": true, + "autoincrement": false } }, "indexes": { "verification_identifier_idx": { "name": "verification_identifier_idx", "columns": [ - { - "expression": "identifier", - "isExpression": false, - "asc": true, - "nulls": "last" - } + "identifier" ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} + "isUnique": false } }, "foreignKeys": {}, "compositePrimaryKeys": {}, "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false + "checkConstraints": {} + }, + "watchlist_item": { + "name": "watchlist_item", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ticker": { + "name": "ticker", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "company_name": { + "name": "company_name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "sector": { + "name": "sector", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "watchlist_user_ticker_uidx": { + "name": "watchlist_user_ticker_uidx", + "columns": [ + "user_id", + "ticker" + ], + "isUnique": true + }, + "watchlist_user_created_idx": { + "name": "watchlist_user_created_idx", + "columns": [ + "user_id", + "created_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "watchlist_item_user_id_user_id_fk": { + "name": "watchlist_item_user_id_user_id_fk", + "tableFrom": "watchlist_item", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} } }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, "views": {}, + "enums": {}, "_meta": { - "columns": {}, "schemas": {}, - "tables": {} + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": {} } } \ No newline at end of file diff --git a/drizzle/meta/0001_snapshot.json b/drizzle/meta/0001_snapshot.json deleted file mode 100644 index 3458924..0000000 --- a/drizzle/meta/0001_snapshot.json +++ /dev/null @@ -1,1502 +0,0 @@ -{ - "id": "088fb564-112f-4e2d-99b9-42844af1f71f", - "prevId": "c490542d-7f2f-49f2-8a4f-813dd6c2e9c5", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.account": { - "name": "account", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "accountId": { - "name": "accountId", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "providerId": { - "name": "providerId", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "userId": { - "name": "userId", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "accessToken": { - "name": "accessToken", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "refreshToken": { - "name": "refreshToken", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "idToken": { - "name": "idToken", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "accessTokenExpiresAt": { - "name": "accessTokenExpiresAt", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "refreshTokenExpiresAt": { - "name": "refreshTokenExpiresAt", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "password": { - "name": "password", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "account_userId_idx": { - "name": "account_userId_idx", - "columns": [ - { - "expression": "userId", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "account_userId_user_id_fk": { - "name": "account_userId_user_id_fk", - "tableFrom": "account", - "tableTo": "user", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.filing": { - "name": "filing", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "integer", - "primaryKey": true, - "notNull": true, - "identity": { - "type": "always", - "name": "filing_id_seq", - "schema": "public", - "increment": "1", - "startWith": "1", - "minValue": "1", - "maxValue": "2147483647", - "cache": "1", - "cycle": false - } - }, - "ticker": { - "name": "ticker", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "filing_type": { - "name": "filing_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "filing_date": { - "name": "filing_date", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "accession_number": { - "name": "accession_number", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "cik": { - "name": "cik", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "company_name": { - "name": "company_name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "filing_url": { - "name": "filing_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "submission_url": { - "name": "submission_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "primary_document": { - "name": "primary_document", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "metrics": { - "name": "metrics", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "analysis": { - "name": "analysis", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "filing_accession_uidx": { - "name": "filing_accession_uidx", - "columns": [ - { - "expression": "accession_number", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "filing_ticker_date_idx": { - "name": "filing_ticker_date_idx", - "columns": [ - { - "expression": "ticker", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "filing_date", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "filing_date_idx": { - "name": "filing_date_idx", - "columns": [ - { - "expression": "filing_date", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.filing_link": { - "name": "filing_link", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "integer", - "primaryKey": true, - "notNull": true, - "identity": { - "type": "always", - "name": "filing_link_id_seq", - "schema": "public", - "increment": "1", - "startWith": "1", - "minValue": "1", - "maxValue": "2147483647", - "cache": "1", - "cycle": false - } - }, - "filing_id": { - "name": "filing_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "link_type": { - "name": "link_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "url": { - "name": "url", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source": { - "name": "source", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'sec'" - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "filing_link_unique_uidx": { - "name": "filing_link_unique_uidx", - "columns": [ - { - "expression": "filing_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "url", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "filing_link_filing_idx": { - "name": "filing_link_filing_idx", - "columns": [ - { - "expression": "filing_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "filing_link_filing_id_filing_id_fk": { - "name": "filing_link_filing_id_filing_id_fk", - "tableFrom": "filing_link", - "tableTo": "filing", - "columnsFrom": [ - "filing_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.holding": { - "name": "holding", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "integer", - "primaryKey": true, - "notNull": true, - "identity": { - "type": "always", - "name": "holding_id_seq", - "schema": "public", - "increment": "1", - "startWith": "1", - "minValue": "1", - "maxValue": "2147483647", - "cache": "1", - "cycle": false - } - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "ticker": { - "name": "ticker", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "shares": { - "name": "shares", - "type": "numeric(30, 6)", - "primaryKey": false, - "notNull": true - }, - "avg_cost": { - "name": "avg_cost", - "type": "numeric(30, 6)", - "primaryKey": false, - "notNull": true - }, - "current_price": { - "name": "current_price", - "type": "numeric(30, 6)", - "primaryKey": false, - "notNull": false - }, - "market_value": { - "name": "market_value", - "type": "numeric(30, 2)", - "primaryKey": false, - "notNull": true - }, - "gain_loss": { - "name": "gain_loss", - "type": "numeric(30, 2)", - "primaryKey": false, - "notNull": true - }, - "gain_loss_pct": { - "name": "gain_loss_pct", - "type": "numeric(30, 2)", - "primaryKey": false, - "notNull": true - }, - "last_price_at": { - "name": "last_price_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "holding_user_ticker_uidx": { - "name": "holding_user_ticker_uidx", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "ticker", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "holding_user_idx": { - "name": "holding_user_idx", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "holding_user_id_user_id_fk": { - "name": "holding_user_id_user_id_fk", - "tableFrom": "holding", - "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.invitation": { - "name": "invitation", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "organizationId": { - "name": "organizationId", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "email": { - "name": "email", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "role": { - "name": "role", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'pending'" - }, - "expiresAt": { - "name": "expiresAt", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "inviterId": { - "name": "inviterId", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "invitation_organizationId_idx": { - "name": "invitation_organizationId_idx", - "columns": [ - { - "expression": "organizationId", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "invitation_email_idx": { - "name": "invitation_email_idx", - "columns": [ - { - "expression": "email", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "invitation_organizationId_organization_id_fk": { - "name": "invitation_organizationId_organization_id_fk", - "tableFrom": "invitation", - "tableTo": "organization", - "columnsFrom": [ - "organizationId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "invitation_inviterId_user_id_fk": { - "name": "invitation_inviterId_user_id_fk", - "tableFrom": "invitation", - "tableTo": "user", - "columnsFrom": [ - "inviterId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.member": { - "name": "member", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "organizationId": { - "name": "organizationId", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "userId": { - "name": "userId", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "role": { - "name": "role", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'member'" - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "member_organizationId_idx": { - "name": "member_organizationId_idx", - "columns": [ - { - "expression": "organizationId", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "member_userId_idx": { - "name": "member_userId_idx", - "columns": [ - { - "expression": "userId", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "member_organizationId_organization_id_fk": { - "name": "member_organizationId_organization_id_fk", - "tableFrom": "member", - "tableTo": "organization", - "columnsFrom": [ - "organizationId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "member_userId_user_id_fk": { - "name": "member_userId_user_id_fk", - "tableFrom": "member", - "tableTo": "user", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.organization": { - "name": "organization", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "slug": { - "name": "slug", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "logo": { - "name": "logo", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "metadata": { - "name": "metadata", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "organization_slug_uidx": { - "name": "organization_slug_uidx", - "columns": [ - { - "expression": "slug", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.portfolio_insight": { - "name": "portfolio_insight", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "integer", - "primaryKey": true, - "notNull": true, - "identity": { - "type": "always", - "name": "portfolio_insight_id_seq", - "schema": "public", - "increment": "1", - "startWith": "1", - "minValue": "1", - "maxValue": "2147483647", - "cache": "1", - "cycle": false - } - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "content": { - "name": "content", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "insight_user_created_idx": { - "name": "insight_user_created_idx", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "portfolio_insight_user_id_user_id_fk": { - "name": "portfolio_insight_user_id_user_id_fk", - "tableFrom": "portfolio_insight", - "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.session": { - "name": "session", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "expiresAt": { - "name": "expiresAt", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "token": { - "name": "token", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "ipAddress": { - "name": "ipAddress", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "userAgent": { - "name": "userAgent", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "userId": { - "name": "userId", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "impersonatedBy": { - "name": "impersonatedBy", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "activeOrganizationId": { - "name": "activeOrganizationId", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "session_token_uidx": { - "name": "session_token_uidx", - "columns": [ - { - "expression": "token", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "session_userId_idx": { - "name": "session_userId_idx", - "columns": [ - { - "expression": "userId", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "session_userId_user_id_fk": { - "name": "session_userId_user_id_fk", - "tableFrom": "session", - "tableTo": "user", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.task_run": { - "name": "task_run", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "task_type": { - "name": "task_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "priority": { - "name": "priority", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "payload": { - "name": "payload", - "type": "jsonb", - "primaryKey": false, - "notNull": true - }, - "result": { - "name": "result", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "error": { - "name": "error", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "attempts": { - "name": "attempts", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "max_attempts": { - "name": "max_attempts", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "workflow_run_id": { - "name": "workflow_run_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "finished_at": { - "name": "finished_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "task_user_created_idx": { - "name": "task_user_created_idx", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "task_status_idx": { - "name": "task_status_idx", - "columns": [ - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "task_workflow_run_uidx": { - "name": "task_workflow_run_uidx", - "columns": [ - { - "expression": "workflow_run_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "task_run_user_id_user_id_fk": { - "name": "task_run_user_id_user_id_fk", - "tableFrom": "task_run", - "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.user": { - "name": "user", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "email": { - "name": "email", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "emailVerified": { - "name": "emailVerified", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "image": { - "name": "image", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "role": { - "name": "role", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "banned": { - "name": "banned", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "banReason": { - "name": "banReason", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "banExpires": { - "name": "banExpires", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "user_email_uidx": { - "name": "user_email_uidx", - "columns": [ - { - "expression": "email", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.verification": { - "name": "verification", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "identifier": { - "name": "identifier", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "expiresAt": { - "name": "expiresAt", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "updatedAt": { - "name": "updatedAt", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "verification_identifier_idx": { - "name": "verification_identifier_idx", - "columns": [ - { - "expression": "identifier", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.watchlist_item": { - "name": "watchlist_item", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "integer", - "primaryKey": true, - "notNull": true, - "identity": { - "type": "always", - "name": "watchlist_item_id_seq", - "schema": "public", - "increment": "1", - "startWith": "1", - "minValue": "1", - "maxValue": "2147483647", - "cache": "1", - "cycle": false - } - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "ticker": { - "name": "ticker", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "company_name": { - "name": "company_name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "sector": { - "name": "sector", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "watchlist_user_ticker_uidx": { - "name": "watchlist_user_ticker_uidx", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "ticker", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "watchlist_user_created_idx": { - "name": "watchlist_user_created_idx", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "watchlist_item_user_id_user_id_fk": { - "name": "watchlist_item_user_id_user_id_fk", - "tableFrom": "watchlist_item", - "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index 9965bb5..82c091a 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -1,19 +1,12 @@ { "version": "7", - "dialect": "postgresql", + "dialect": "sqlite", "entries": [ { "idx": 0, - "version": "7", - "when": 1771967961625, - "tag": "0000_tense_centennial", - "breakpoints": true - }, - { - "idx": 1, - "version": "7", - "when": 1772076911227, - "tag": "0001_boring_toad", + "version": "6", + "when": 1772137733427, + "tag": "0000_cold_silver_centurion", "breakpoints": true } ] diff --git a/lib/auth.ts b/lib/auth.ts index 7153fc3..181891b 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -20,7 +20,7 @@ const secret = process.env.BETTER_AUTH_SECRET?.trim() || undefined; export const auth = betterAuth({ database: drizzleAdapter(db, { - provider: 'pg', + provider: 'sqlite', schema: authSchema }), baseURL, diff --git a/lib/server/db/index.ts b/lib/server/db/index.ts index df38140..7828041 100644 --- a/lib/server/db/index.ts +++ b/lib/server/db/index.ts @@ -1,37 +1,54 @@ -import { drizzle } from 'drizzle-orm/node-postgres'; -import { Pool } from 'pg'; +import { mkdirSync } from 'node:fs'; +import { dirname } from 'node:path'; +import { Database } from 'bun:sqlite'; +import { drizzle } from 'drizzle-orm/bun-sqlite'; import { schema } from './schema'; type AppDrizzleDb = ReturnType; declare global { // eslint-disable-next-line no-var - var __fiscalPgPool: Pool | undefined; + var __fiscalSqliteClient: Database | undefined; // eslint-disable-next-line no-var var __fiscalDrizzleDb: AppDrizzleDb | undefined; } -function getConnectionString() { - const connectionString = process.env.DATABASE_URL?.trim(); - if (!connectionString) { - throw new Error('DATABASE_URL is required for PostgreSQL.'); +function getDatabasePath() { + const raw = process.env.DATABASE_URL?.trim() || 'file:data/fiscal.sqlite'; + let databasePath = raw.startsWith('file:') ? raw.slice(5) : raw; + + if (databasePath.startsWith('///')) { + databasePath = databasePath.slice(2); } - return connectionString; + if (!databasePath) { + throw new Error('DATABASE_URL must point to a SQLite file path.'); + } + + return databasePath; } -export function getPool() { - if (!globalThis.__fiscalPgPool) { - globalThis.__fiscalPgPool = new Pool({ - connectionString: getConnectionString() - }); +export function getSqliteClient() { + if (!globalThis.__fiscalSqliteClient) { + const databasePath = getDatabasePath(); + + if (databasePath !== ':memory:') { + mkdirSync(dirname(databasePath), { recursive: true }); + } + + const client = new Database(databasePath, { create: true }); + client.exec('PRAGMA foreign_keys = ON;'); + client.exec('PRAGMA journal_mode = WAL;'); + client.exec('PRAGMA busy_timeout = 5000;'); + + globalThis.__fiscalSqliteClient = client; } - return globalThis.__fiscalPgPool; + return globalThis.__fiscalSqliteClient; } function createDb() { - return drizzle(getPool(), { schema }); + return drizzle(getSqliteClient(), { schema }); } export const db = globalThis.__fiscalDrizzleDb ?? createDb(); diff --git a/lib/server/db/schema.ts b/lib/server/db/schema.ts index c53efa8..f6a3cc6 100644 --- a/lib/server/db/schema.ts +++ b/lib/server/db/schema.ts @@ -1,14 +1,11 @@ import { - boolean, index, integer, - jsonb, numeric, - pgTable, + sqliteTable, text, - timestamp, uniqueIndex -} from 'drizzle-orm/pg-core'; +} from 'drizzle-orm/sqlite-core'; type FilingMetrics = { revenue: number | null; @@ -26,48 +23,42 @@ type FilingAnalysis = { }; const authDateColumn = { - withTimezone: true, - mode: 'date' + mode: 'timestamp_ms' } as const; -const appDateColumn = { - withTimezone: true, - mode: 'string' -} as const; - -export const user = pgTable('user', { +export const user = sqliteTable('user', { id: text('id').primaryKey().notNull(), name: text('name').notNull(), email: text('email').notNull(), - emailVerified: boolean('emailVerified').notNull().default(false), + emailVerified: integer('emailVerified', { mode: 'boolean' }).notNull().default(false), image: text('image'), - createdAt: timestamp('createdAt', authDateColumn).notNull(), - updatedAt: timestamp('updatedAt', authDateColumn).notNull(), + createdAt: integer('createdAt', authDateColumn).notNull(), + updatedAt: integer('updatedAt', authDateColumn).notNull(), role: text('role'), - banned: boolean('banned').default(false), + banned: integer('banned', { mode: 'boolean' }).default(false), banReason: text('banReason'), - banExpires: timestamp('banExpires', authDateColumn) + banExpires: integer('banExpires', authDateColumn) }, (table) => ({ userEmailUnique: uniqueIndex('user_email_uidx').on(table.email) })); -export const organization = pgTable('organization', { +export const organization = sqliteTable('organization', { id: text('id').primaryKey().notNull(), name: text('name').notNull(), slug: text('slug').notNull(), logo: text('logo'), - createdAt: timestamp('createdAt', authDateColumn).notNull(), + createdAt: integer('createdAt', authDateColumn).notNull(), metadata: text('metadata') }, (table) => ({ organizationSlugUnique: uniqueIndex('organization_slug_uidx').on(table.slug) })); -export const session = pgTable('session', { +export const session = sqliteTable('session', { id: text('id').primaryKey().notNull(), - expiresAt: timestamp('expiresAt', authDateColumn).notNull(), + expiresAt: integer('expiresAt', authDateColumn).notNull(), token: text('token').notNull(), - createdAt: timestamp('createdAt', authDateColumn).notNull(), - updatedAt: timestamp('updatedAt', authDateColumn).notNull(), + createdAt: integer('createdAt', authDateColumn).notNull(), + updatedAt: integer('updatedAt', authDateColumn).notNull(), ipAddress: text('ipAddress'), userAgent: text('userAgent'), userId: text('userId').notNull().references(() => user.id, { onDelete: 'cascade' }), @@ -78,7 +69,7 @@ export const session = pgTable('session', { sessionUserIdIndex: index('session_userId_idx').on(table.userId) })); -export const account = pgTable('account', { +export const account = sqliteTable('account', { id: text('id').primaryKey().notNull(), accountId: text('accountId').notNull(), providerId: text('providerId').notNull(), @@ -86,84 +77,84 @@ export const account = pgTable('account', { accessToken: text('accessToken'), refreshToken: text('refreshToken'), idToken: text('idToken'), - accessTokenExpiresAt: timestamp('accessTokenExpiresAt', authDateColumn), - refreshTokenExpiresAt: timestamp('refreshTokenExpiresAt', authDateColumn), + accessTokenExpiresAt: integer('accessTokenExpiresAt', authDateColumn), + refreshTokenExpiresAt: integer('refreshTokenExpiresAt', authDateColumn), scope: text('scope'), password: text('password'), - createdAt: timestamp('createdAt', authDateColumn).notNull(), - updatedAt: timestamp('updatedAt', authDateColumn).notNull() + createdAt: integer('createdAt', authDateColumn).notNull(), + updatedAt: integer('updatedAt', authDateColumn).notNull() }, (table) => ({ accountUserIdIndex: index('account_userId_idx').on(table.userId) })); -export const verification = pgTable('verification', { +export const verification = sqliteTable('verification', { id: text('id').primaryKey().notNull(), identifier: text('identifier').notNull(), value: text('value').notNull(), - expiresAt: timestamp('expiresAt', authDateColumn).notNull(), - createdAt: timestamp('createdAt', authDateColumn).notNull(), - updatedAt: timestamp('updatedAt', authDateColumn).notNull() + expiresAt: integer('expiresAt', authDateColumn).notNull(), + createdAt: integer('createdAt', authDateColumn).notNull(), + updatedAt: integer('updatedAt', authDateColumn).notNull() }, (table) => ({ verificationIdentifierIndex: index('verification_identifier_idx').on(table.identifier) })); -export const member = pgTable('member', { +export const member = sqliteTable('member', { id: text('id').primaryKey().notNull(), organizationId: text('organizationId').notNull().references(() => organization.id, { onDelete: 'cascade' }), userId: text('userId').notNull().references(() => user.id, { onDelete: 'cascade' }), role: text('role').notNull().default('member'), - createdAt: timestamp('createdAt', authDateColumn).notNull() + createdAt: integer('createdAt', authDateColumn).notNull() }, (table) => ({ memberOrganizationIdIndex: index('member_organizationId_idx').on(table.organizationId), memberUserIdIndex: index('member_userId_idx').on(table.userId) })); -export const invitation = pgTable('invitation', { +export const invitation = sqliteTable('invitation', { id: text('id').primaryKey().notNull(), organizationId: text('organizationId').notNull().references(() => organization.id, { onDelete: 'cascade' }), email: text('email').notNull(), role: text('role'), status: text('status').notNull().default('pending'), - expiresAt: timestamp('expiresAt', authDateColumn).notNull(), - createdAt: timestamp('createdAt', authDateColumn).notNull(), + expiresAt: integer('expiresAt', authDateColumn).notNull(), + createdAt: integer('createdAt', authDateColumn).notNull(), inviterId: text('inviterId').notNull().references(() => user.id, { onDelete: 'cascade' }) }, (table) => ({ invitationOrganizationIdIndex: index('invitation_organizationId_idx').on(table.organizationId), invitationEmailIndex: index('invitation_email_idx').on(table.email) })); -export const watchlistItem = pgTable('watchlist_item', { - id: integer('id').generatedAlwaysAsIdentity().primaryKey(), +export const watchlistItem = sqliteTable('watchlist_item', { + id: integer('id').primaryKey({ autoIncrement: true }), user_id: text('user_id').notNull().references(() => user.id, { onDelete: 'cascade' }), ticker: text('ticker').notNull(), company_name: text('company_name').notNull(), sector: text('sector'), - created_at: timestamp('created_at', appDateColumn).notNull() + created_at: text('created_at').notNull() }, (table) => ({ watchlistUserTickerUnique: uniqueIndex('watchlist_user_ticker_uidx').on(table.user_id, table.ticker), watchlistUserCreatedIndex: index('watchlist_user_created_idx').on(table.user_id, table.created_at) })); -export const holding = pgTable('holding', { - id: integer('id').generatedAlwaysAsIdentity().primaryKey(), +export const holding = sqliteTable('holding', { + id: integer('id').primaryKey({ autoIncrement: true }), user_id: text('user_id').notNull().references(() => user.id, { onDelete: 'cascade' }), ticker: text('ticker').notNull(), - shares: numeric('shares', { precision: 30, scale: 6 }).notNull(), - avg_cost: numeric('avg_cost', { precision: 30, scale: 6 }).notNull(), - current_price: numeric('current_price', { precision: 30, scale: 6 }), - market_value: numeric('market_value', { precision: 30, scale: 2 }).notNull(), - gain_loss: numeric('gain_loss', { precision: 30, scale: 2 }).notNull(), - gain_loss_pct: numeric('gain_loss_pct', { precision: 30, scale: 2 }).notNull(), - last_price_at: timestamp('last_price_at', appDateColumn), - created_at: timestamp('created_at', appDateColumn).notNull(), - updated_at: timestamp('updated_at', appDateColumn).notNull() + shares: numeric('shares').notNull(), + avg_cost: numeric('avg_cost').notNull(), + current_price: numeric('current_price'), + market_value: numeric('market_value').notNull(), + gain_loss: numeric('gain_loss').notNull(), + gain_loss_pct: numeric('gain_loss_pct').notNull(), + last_price_at: text('last_price_at'), + created_at: text('created_at').notNull(), + updated_at: text('updated_at').notNull() }, (table) => ({ holdingUserTickerUnique: uniqueIndex('holding_user_ticker_uidx').on(table.user_id, table.ticker), holdingUserIndex: index('holding_user_idx').on(table.user_id) })); -export const filing = pgTable('filing', { - id: integer('id').generatedAlwaysAsIdentity().primaryKey(), +export const filing = sqliteTable('filing', { + id: integer('id').primaryKey({ autoIncrement: true }), ticker: text('ticker').notNull(), filing_type: text('filing_type').$type<'10-K' | '10-Q' | '8-K'>().notNull(), filing_date: text('filing_date').notNull(), @@ -173,56 +164,56 @@ export const filing = pgTable('filing', { filing_url: text('filing_url'), submission_url: text('submission_url'), primary_document: text('primary_document'), - metrics: jsonb('metrics').$type(), - analysis: jsonb('analysis').$type(), - created_at: timestamp('created_at', appDateColumn).notNull(), - updated_at: timestamp('updated_at', appDateColumn).notNull() + metrics: text('metrics', { mode: 'json' }).$type(), + analysis: text('analysis', { mode: 'json' }).$type(), + created_at: text('created_at').notNull(), + updated_at: text('updated_at').notNull() }, (table) => ({ filingAccessionUnique: uniqueIndex('filing_accession_uidx').on(table.accession_number), filingTickerDateIndex: index('filing_ticker_date_idx').on(table.ticker, table.filing_date), filingDateIndex: index('filing_date_idx').on(table.filing_date) })); -export const filingLink = pgTable('filing_link', { - id: integer('id').generatedAlwaysAsIdentity().primaryKey(), +export const filingLink = sqliteTable('filing_link', { + id: integer('id').primaryKey({ autoIncrement: true }), filing_id: integer('filing_id').notNull().references(() => filing.id, { onDelete: 'cascade' }), link_type: text('link_type').notNull(), url: text('url').notNull(), source: text('source').notNull().default('sec'), - created_at: timestamp('created_at', appDateColumn).notNull() + created_at: text('created_at').notNull() }, (table) => ({ filingLinkUnique: uniqueIndex('filing_link_unique_uidx').on(table.filing_id, table.url), filingLinkFilingIndex: index('filing_link_filing_idx').on(table.filing_id) })); -export const taskRun = pgTable('task_run', { +export const taskRun = sqliteTable('task_run', { id: text('id').primaryKey().notNull(), user_id: text('user_id').notNull().references(() => user.id, { onDelete: 'cascade' }), task_type: text('task_type').$type<'sync_filings' | 'refresh_prices' | 'analyze_filing' | 'portfolio_insights'>().notNull(), status: text('status').$type<'queued' | 'running' | 'completed' | 'failed'>().notNull(), priority: integer('priority').notNull(), - payload: jsonb('payload').$type>().notNull(), - result: jsonb('result').$type | null>(), + payload: text('payload', { mode: 'json' }).$type>().notNull(), + result: text('result', { mode: 'json' }).$type | null>(), error: text('error'), attempts: integer('attempts').notNull(), max_attempts: integer('max_attempts').notNull(), workflow_run_id: text('workflow_run_id'), - created_at: timestamp('created_at', appDateColumn).notNull(), - updated_at: timestamp('updated_at', appDateColumn).notNull(), - finished_at: timestamp('finished_at', appDateColumn) + created_at: text('created_at').notNull(), + updated_at: text('updated_at').notNull(), + finished_at: text('finished_at') }, (table) => ({ taskUserCreatedIndex: index('task_user_created_idx').on(table.user_id, table.created_at), taskStatusIndex: index('task_status_idx').on(table.status), taskWorkflowRunUnique: uniqueIndex('task_workflow_run_uidx').on(table.workflow_run_id) })); -export const portfolioInsight = pgTable('portfolio_insight', { - id: integer('id').generatedAlwaysAsIdentity().primaryKey(), +export const portfolioInsight = sqliteTable('portfolio_insight', { + id: integer('id').primaryKey({ autoIncrement: true }), user_id: text('user_id').notNull().references(() => user.id, { onDelete: 'cascade' }), provider: text('provider').notNull(), model: text('model').notNull(), content: text('content').notNull(), - created_at: timestamp('created_at', appDateColumn).notNull() + created_at: text('created_at').notNull() }, (table) => ({ insightUserCreatedIndex: index('insight_user_created_idx').on(table.user_id, table.created_at) })); diff --git a/package.json b/package.json index e7f5ece..967b292 100644 --- a/package.json +++ b/package.json @@ -9,13 +9,12 @@ "start": "bun --bun next start", "lint": "bun --bun tsc --noEmit", "db:generate": "bun x drizzle-kit generate", - "db:migrate": "bun x drizzle-kit migrate", - "workflow:setup": "bun x workflow-postgres-setup" + "db:migrate": "bun x drizzle-kit migrate" }, "dependencies": { "@elysiajs/eden": "^1.4.8", + "@libsql/client": "^0.17.0", "@tailwindcss/postcss": "^4.2.1", - "@workflow/world-postgres": "^4.1.0-beta.36", "better-auth": "^1.4.19", "clsx": "^2.1.1", "date-fns": "^4.1.0", @@ -23,7 +22,6 @@ "elysia": "latest", "lucide-react": "^0.575.0", "next": "^16.1.6", - "pg": "^8.18.0", "react": "^19.2.4", "react-dom": "^19.2.4", "recharts": "^3.7.0", @@ -31,10 +29,10 @@ }, "devDependencies": { "@types/node": "^25.3.0", - "@types/pg": "^8.16.0", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", "autoprefixer": "^10.4.24", + "bun-types": "^1.3.10", "drizzle-kit": "^0.31.4", "postcss": "^8.5.6", "tailwindcss": "^4.2.1", diff --git a/tsconfig.json b/tsconfig.json index e7ff3a2..0619904 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,6 +13,9 @@ "esModuleInterop": true, "module": "esnext", "moduleResolution": "bundler", + "types": [ + "bun-types" + ], "resolveJsonModule": true, "isolatedModules": true, "jsx": "react-jsx",