diff --git a/.dockerignore b/.dockerignore
index f4719a3..dd6325c 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -3,6 +3,7 @@
.cache
.swc
.workflow-data
+rust/target
# Dependencies
node_modules
@@ -21,12 +22,22 @@ data
.git
.gitignore
.gitea
+.github
+.claude
# Test and local tooling artifacts
.playwright-cli
e2e
output
+test
+playwright.config.ts
+vitest.config.mts
+*.test.ts
# Docs and generated metadata
README.md
+agents.md
+E2E_UX_REPORT_*.md
+doc
+docs
tsconfig.tsbuildinfo
diff --git a/doc/deployment-benchmark-and-coolify.md b/doc/deployment-benchmark-and-coolify.md
new file mode 100644
index 0000000..56a66d1
--- /dev/null
+++ b/doc/deployment-benchmark-and-coolify.md
@@ -0,0 +1,52 @@
+# Deployment Benchmark And Coolify Notes
+
+## Local build timings
+
+Measured on this workstation on 2026-03-21:
+
+- `bun run build` cold-ish run: `26.00s` wall time
+- `bun run build` warm run: `20.68s` wall time
+- Turbopack compile phase inside those runs: `8.8s` cold-ish, `7.8s` warm
+
+Observed repeated work on every build:
+
+- taxonomy generation
+- workflow manifest generation
+- TypeScript validation performed by Next during build
+- static page generation
+
+## Docker attempt
+
+The local Docker daemon did not respond during validation. `docker build` and `docker info` both stalled until externally timed out, so the image could not be run end-to-end on this machine in this session.
+
+That means the application build was validated locally, but container execution still depends on a healthy Docker engine on the target host.
+
+## Changes made for deployment
+
+- Added a `prod-deps` stage so the runtime image uses production dependencies instead of the full development install.
+- Bundled `scripts/bootstrap-production.ts` into `bootstrap-production.js` during image build so the runtime image no longer needs the full TypeScript source tree just to run startup bootstrap.
+- Changed the runtime command to execute the bundled bootstrap directly and then `exec` the standalone Next server.
+- Set `HOSTNAME=0.0.0.0` in the runtime image so direct Dockerfile-based deployments behave correctly without compose overrides.
+- Reduced the Docker build context by excluding docs, tests, local metadata, and `rust/target`.
+
+## Coolify requirements
+
+This project is viable on Coolify if it is deployed as a multi-service Docker Compose stack, not as a single app without Postgres.
+
+Required runtime conditions:
+
+- single replica only
+- persistent Docker volumes for `/app/data` and Postgres data
+- `WORKFLOW_TARGET_WORLD=@workflow/world-postgres`
+- `WORKFLOW_POSTGRES_URL=postgres://workflow:workflow@workflow-postgres:5432/workflow`
+- `DATABASE_URL=file:/app/data/fiscal.sqlite`
+- valid `BETTER_AUTH_SECRET`
+- `BETTER_AUTH_BASE_URL` and `BETTER_AUTH_TRUSTED_ORIGINS` set to the final public Coolify URL
+
+## Highest-impact deployment optimizations
+
+1. Keep build cache warm on the same Coolify builder. The Dockerfile now benefits from Bun dependency cache mounts, a separate production dependency stage, and `.next/cache`.
+2. Avoid invalidating image builds with non-runtime file changes. The updated `.dockerignore` keeps docs, tests, and local artifacts out of the build context.
+3. Consider moving taxonomy generation out of the hot path if the data does not change on every deploy. It currently runs on every application build.
+4. Consider splitting bootstrap responsibilities further if startup latency becomes a problem. Right now startup still performs workflow setup and SQLite migrations before the app binds its port.
+5. If horizontal scaling is required later, move the app database off SQLite. Coolify can run this as-is, but only safely as a single-writer instance.
diff --git a/drizzle/0012_crazy_molecule_man.sql b/drizzle/0012_crazy_molecule_man.sql
index 84f8a4e..659bfe5 100644
--- a/drizzle/0012_crazy_molecule_man.sql
+++ b/drizzle/0012_crazy_molecule_man.sql
@@ -1,18 +1,3 @@
-CREATE TABLE `company_financial_bundle` (
- `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
- `ticker` text NOT NULL,
- `surface_kind` text NOT NULL,
- `cadence` text NOT NULL,
- `bundle_version` integer NOT NULL,
- `source_snapshot_ids` text NOT NULL,
- `source_signature` text NOT NULL,
- `payload` text NOT NULL,
- `created_at` text NOT NULL,
- `updated_at` text NOT NULL
-);
---> statement-breakpoint
-CREATE UNIQUE INDEX `company_financial_bundle_uidx` ON `company_financial_bundle` (`ticker`,`surface_kind`,`cadence`);--> statement-breakpoint
-CREATE INDEX `company_financial_bundle_ticker_idx` ON `company_financial_bundle` (`ticker`,`updated_at`);--> statement-breakpoint
CREATE TABLE `company_overview_cache` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`user_id` text NOT NULL,
@@ -358,4 +343,4 @@ ALTER TABLE `watchlist_item` ADD `status` text DEFAULT 'backlog' NOT NULL;--> st
ALTER TABLE `watchlist_item` ADD `priority` text DEFAULT 'medium' NOT NULL;--> statement-breakpoint
ALTER TABLE `watchlist_item` ADD `updated_at` text NOT NULL;--> statement-breakpoint
ALTER TABLE `watchlist_item` ADD `last_reviewed_at` text;--> statement-breakpoint
-CREATE INDEX `watchlist_user_updated_idx` ON `watchlist_item` (`user_id`,`updated_at`);
\ No newline at end of file
+CREATE INDEX `watchlist_user_updated_idx` ON `watchlist_item` (`user_id`,`updated_at`);
diff --git a/next-env.d.ts b/next-env.d.ts
index c4b7818..9edff1c 100644
--- a/next-env.d.ts
+++ b/next-env.d.ts
@@ -1,6 +1,6 @@
///
///
-import "./.next/dev/types/routes.d.ts";
+import "./.next/types/routes.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.