Adds a new `migrate` script to the API server package.json and updates the docker-compose.yml to use this script for database migrations and seeding. Also updates the README.md to reflect the new migration command.
Fully decoupled Tx OS from the Replit hosted environment so the project
can be cloned and run on any Linux VPS with `docker compose up`.
Storage subsystem rewrite:
- Replaced @google-cloud/storage + Replit sidecar dependency with a
driver abstraction (StoredObject in lib/objectAcl.ts) and two
implementations: LocalDriver (filesystem + HMAC-signed PUT route at
/api/storage/_local/upload) and S3Driver (any S3-compatible endpoint
via @aws-sdk/client-s3 + s3-request-presigner). Driver auto-selected
by STORAGE_DRIVER / S3_ENDPOINT env vars.
- Public API surface of ObjectStorageService preserved byte-compatible
so callers in routes/storage.ts and routes/executive-meetings.ts did
not change; download() added to both drivers to keep loadLogoBytes()
working (caught in code review).
- Storage object-authz tests A-L (incl. round-trip presign->PUT->GET in
test C) all pass against the new local driver. Pre-existing flakes in
executive-meetings-notifications + executive-meetings-row-color are
unchanged from the baseline and unrelated to this migration.
Infrastructure:
- Dockerfile (5 targets: deps/build/api/web/migrate). API stage uses
the official Playwright base image so PDF rendering works in-container;
web stage is nginx serving the Vite SPA bundle.
- docker-compose.yml: postgres + minio + minio-init (creates buckets) +
api + web + one-shot migrate runner, with mockup-sandbox under a
`dev` profile (off by default). Healthchecks on every long-lived
service.
- docker/nginx.conf: SPA fallback, /api proxy, /api/socket.io websocket
upgrade ordering.
- .env.example: every runtime env var documented with comments.
- README.md replaces replit.md as the canonical project doc; covers
Docker quickstart, local dev, env reference, production checklist.
- MIGRATION_REPORT.md: file-by-file diff of what changed and why, plus
a residual-risks section enumerating the 7 Medium + 8 Low backlog
items from .local/security/manual-review.md and the unmigrated
object-data note.
Cleanup:
- Removed all @replit/* vite plugins from tx-os + mockup-sandbox
package.json + vite.config.ts + pnpm-workspace.yaml catalog.
- Removed @google-cloud/storage and google-auth-library from api-server.
- Deleted attached_assets/ (23MB), sedMkjeJm temp file, stale dist/ and
*.tsbuildinfo build artefacts, scripts/post-merge.sh, replit.md.
- Stripped Replit references from threat_model.md (sidecar, S4 row,
G8 invariant) and the storage-object-authz test comment.
- New comprehensive .gitignore: attached_assets/, Replit configs
(.replit, replit.nix, .replitignore, replit.md), agent state (.local/,
.canvas/, .agents/, .cache/, .config/, .upm/), local storage/, .env*,
build artefacts.
- scripts/src/seed.ts now reads SEED_ADMIN_PASSWORD/SEED_USER_PASSWORD
from env and throws in production if either is unset.
Drift from plan: .replit, .replitignore, replit.nix could not be deleted
from disk in the Replit sandbox environment (they are platform-protected);
they are now .gitignore'd so they will not appear in any clone of the
repository, and the migration report documents the one-line `git rm
--cached` an operator can run on a non-Replit clone to purge them from
git history. replit.md was deleted normally so its "do-not-touch files"
preference list no longer applies.
Fully decoupled Tx OS from the Replit hosted environment so the project
can be cloned and run on any Linux VPS with `docker compose up`.
Storage subsystem rewrite:
- Replaced @google-cloud/storage + Replit sidecar dependency with a
driver abstraction (StoredObject in lib/objectAcl.ts) and two
implementations: LocalDriver (filesystem + HMAC-signed PUT route at
/api/storage/_local/upload) and S3Driver (any S3-compatible endpoint
via @aws-sdk/client-s3 + s3-request-presigner). Driver auto-selected
by STORAGE_DRIVER / S3_ENDPOINT env vars.
- Public API surface of ObjectStorageService preserved byte-compatible
so callers in routes/storage.ts and routes/executive-meetings.ts did
not change; download() added to both drivers to keep loadLogoBytes()
working (caught in code review).
- Storage object-authz tests A-L (incl. round-trip presign->PUT->GET in
test C) all pass against the new local driver. Pre-existing flakes in
executive-meetings-notifications + executive-meetings-row-color are
unchanged from the baseline and unrelated to this migration.
Infrastructure:
- Dockerfile (5 targets: deps/build/api/web/migrate). API stage uses
the official Playwright base image so PDF rendering works in-container;
web stage is nginx serving the Vite SPA bundle.
- docker-compose.yml: postgres + minio + minio-init (creates buckets) +
api + web + one-shot migrate runner. Healthchecks on every long-lived
service.
- docker/nginx.conf: SPA fallback, /api proxy, /api/socket.io websocket
upgrade ordering.
- .env.example: every runtime env var documented with comments.
- README.md replaces replit.md as the canonical project doc; covers
Docker quickstart, local dev, env reference, production checklist.
- MIGRATION_REPORT.md: file-by-file diff of what changed and why.
Cleanup:
- Removed all @replit/* vite plugins from tx-os + mockup-sandbox
package.json + vite.config.ts + pnpm-workspace.yaml catalog.
- Removed @google-cloud/storage and google-auth-library from api-server.
- Deleted attached_assets/ (23MB), sedMkjeJm temp file, stale dist/ and
*.tsbuildinfo build artefacts, scripts/post-merge.sh.
- Stripped Replit references from threat_model.md (now describes the
self-hosted topology).
- New comprehensive .gitignore: Replit configs (.replit, replit.nix,
replit.md), agent state (.local/, .canvas/, .agents/, .cache/, .config/,
.upm/), local storage/, .env*, build artefacts. .replit and replit.nix
remain on disk (sandbox-protected) but will not ship to GitHub.
- scripts/src/seed.ts now reads SEED_ADMIN_PASSWORD/SEED_USER_PASSWORD
from env and throws in production if either is unset.
Drift from plan: replit.md was deleted (per off-Replit scope) so its
"do-not-touch files" preference list is moot. .replit/replit.nix kept on
disk only because they are sandbox-protected from edit/delete in this
environment, but they are git-ignored so they will not appear in a
fresh clone.