Skip to content

Bugfix/upload - #222

Closed
romanbsd wants to merge 50 commits into
trycompai:mainfrom
jobsteward:bugfix/upload
Closed

romanbsd wants to merge 50 commits into
trycompai:mainfrom
jobsteward:bugfix/upload

Conversation

@romanbsd

@romanbsd romanbsd commented Sep 14, 2026

Copy link
Copy Markdown

Summary by cubic

Fixes asset uploads by replacing the public upload workflows with organization- and project-scoped asset resources served at root resource paths. The branch also merges the platform's multi-tenant, Kaneo, and XMPP gateway work into release, so the diff is far larger than the upload fix alone.

Migration

  • vendor/kaneo is now a git submodule; run git submodule update --init.
  • CI now targets master; the auto-PR, PR-base, PR-title, and release workflows were removed, and the Postgres credentials changed from postgres/postgres to crm/crm.

Written for commit fdeb4fa. Summary will update on new commits.

Review in cubic

carhartlewis and others added 30 commits August 7, 2026 11:38
Implement XMPP gateway and expose agents' capabilities
* feat: add general contractor project workflow

* refactor: DRY contact name and primary contact derivation

* fix(api): satisfy anti-slop lint in deal contact and gc field updates

* fix: address PR review feedback on project workflow

* fix: require customers for construction projects

* docs: map database to construction workflow

* refactor: remove unsupported construction fields

* fix: align customer deletion copy

* docs: track construction changes

* refactor: restore upstream application UI

* docs: update construction change map

* fix: preserve upstream project mappings

* test: isolate auth environment defaults

* feat: retain minimal construction CRM changes

* docs: align construction mapping terms

* fix: restore CRM vocabulary in construction POC

* fix: consolidate additive CRM migration

---------

Co-authored-by: Roman Shterenzon <roman.shterenzon@gmail.com>
Integrate Kaneo's project management into the CRM without reimplementation
and without a second schema.

- Kaneo is a git submodule at vendor/kaneo pointing at the crm-integration
  branch of the romanbsd/kaneo fork, which carries the CRM deltas.
- One Postgres schema, owned by Prisma. The 32 kaneo tables are generated
  from an ORM-agnostic abstract model (packages/kaneo-domain), with a
  Drizzle binding and a parity test proving the generated schema matches
  what kaneo's code expects. kaneo tables use snake_case physical columns;
  shared auth tables keep the CRM's camelCase. activity and invitation are
  renamed to task_activity and workspace_invitation to avoid collisions.
- kaneo's own Hono controllers and web UI are mounted and served: dev:kaneo
  boots the API against the shared database, serves the web SPA, proxies
  /api and bridges /ws. kaneo's startup Drizzle migrations are gated.
- One session cookie (crm.session_token) valid at both apps, one shared
  Better Auth identity, and CRM roles mapped onto kaneo's on sign-in.
- The eve agent reads projects and tasks through Prisma and drives writes
  through kaneo's extracted controller functions directly, acting as the
  workspace owner.

Documented in vendor/FORK-DELTA.md, adrs/kaneo.md and
docs/kaneo-integration.md.
A POST /push-tokens endpoint stores a device FCM token for the signed-in
user (upsert by token, transferred to the latest owner), and DELETE
/push-tokens removes it if it belongs to the caller. Tokens are validated
with zod at the boundary (platform is ios|android). Add the push_token
table, the module wiring, and e2e coverage for the unauthenticated paths.
* fix: preserve app build environment

* fix(auth): allow mixed Google sign-in domains

* feat(app): add public legal pages
dpaluy and others added 20 commits September 6, 2026 20:16
* feat: add customer and project asset storage

* fix: validate system message before upload replay

* docs: set JobSteward pull request repository

* refactor: keep asset code files within 200 lines
Raise the declared toolchain from bun 1.3.12 to 1.4.2 in packageManager
and devEngines. The lockfile format is unchanged; bun 1.4.2 reads and
writes it identically and a frozen install resolves cleanly.
* chore(deps): upgrade all dependencies to latest versions

Upgrades eve, ai, next, react, typescript, prisma, better-auth, biome, oxlint, turbo, and the remaining manifests to their latest versions.

Fixes incompatibilities introduced by the upgrades:
- eve 0.52.3: ClientSessions.attach() replaces session(), ChannelFrom/ChannelSource replace SendFn, respond() is a separate channel method.
- @pierre/diffs 1.4.1: new Editor/FileOptions generics.
- typescript 7 (tsgo): explicit node types in agent-xmpp tsconfigs.
- better-auth 1.7.3: regenerated the oauth-provider patch.
- prisma 7 capped at 7.10.0 (8.x requires a config-file migration).

* refactor: dedupe builder dispatch parsing and agent model fallback

Extract shared builder input-response predicate and delivery-part
builder so custom-agent-dispatch parses the submission JSON once
instead of up to three times. Add defaultAgentModelResult() to
replace five duplicated fallback object literals across agent
entrypoints. Fix indentation and non-null assertions flagged by
biome in packages/agent-xmpp/core/src/schema.ts. Add
@better-auth/core to packages/auth dependencies.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix: satisfy anti-slop lint on defaultAgentModelResult

Drop the explicit return type annotation so TypeScript keeps the
literal-typed inference from DEFAULT_AGENT_MODEL instead of widening
it to string/number.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
* feat: add native multi-tenancy

* fix: tenant-scope customer assets

* update ci.yml

* fix: declare @better-auth/core as direct dependency in @crm/auth

slack-grant.ts imports @better-auth/core/context but the package
was never listed as a dependency, relying on phantom hoisting.
Multiple @better-auth/core versions in the tree made resolution
nondeterministic and CI hoisted a version without the symlink,
failing check-types with TS2307.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix: sort test imports to satisfy biome lint

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix: sort imports and format per biome across rebase diff

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* remove workflows

* fix lint

* fix: satisfy anti-slop lint boundary-parsing rules

Fixes the lint:slop CI failure. Replaces inline Record<string, unknown>
and typeof-based narrowing with named types and instanceof/Zod parsing
at real I/O boundaries. Moves api-key-principal and adds
active-organization-claim parsers into packages/validation, matching
the repo's parse-at-boundary convention.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nRJf8FVnwdjmSwgBt7tuX

* fix: give real-worker schema test more headroom on CI

The "starts source workers with the declared loader" test spins up a
real worker_threads worker (tsx-loaded), unlike the mocked worker in
schema-worker-lineage.test.ts. Its default 500ms budget is tuned for
production safety, not CI cold-start latency, so a loaded CI runner
timed it out at 502ms. Passes an explicit 5s timeout for this one
integration-style test only; production default is unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nRJf8FVnwdjmSwgBt7tuX

* fix: raise both bun's per-test timeout and the worker budget

Previous fix only bumped validateJsonBounded's internal timeoutMs to
5000ms, missing that bun:test's own default per-test timeout is also
5000ms. Both fired at once, so bun killed the test before the internal
promise could even reject on its own terms. Raise the test timeout to
20s and the internal budget to 15s, giving real headroom on a
resource-constrained CI runner. Verified against a Linux bun 1.4.2
container.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nRJf8FVnwdjmSwgBt7tuX

* fix: stop spawning schema workers with a Node tsx loader under bun

Root cause of the hanging schema.test.ts: createSchemaWorker passed
execArgv: ["--import", "tsx"] when spawning the source-mode worker.
Everything in this repo runs under bun, not Node, and bun already
runs .ts worker files natively without any loader hook. Verified with
a raw Worker spawn that bun runs the .ts file fine with no execArgv at
all. On Linux x64 (the GitHub Actions runner) that unnecessary flag
combination silently hung the worker forever - neither 5s nor 15s
budgets helped because the worker never came online, not because it
was slow. Confirmed against a Linux bun 1.4.2 container before and
after.

Removes the now-dead tsx devDependency and the execArgv option, and
reverts the test back to the default timeout now that the real fix
lands.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nRJf8FVnwdjmSwgBt7tuX

* diag: surface the real worker failure reason in CI logs

Two prior fixes (longer timeouts, removing execArgv) did not resolve
this test's failure on the GitHub Actions Linux x64 runner, and it is
not reproducible on macOS ARM64 or a native Linux ARM64 bun container
(x64 emulation via QEMU crashes bun itself with a memory-exhaustion
assertion, unrelated to the real bug, so it gives no signal). Every
prior CI failure only showed "promise rejected" with no reason.

Logs worker error/exit events to stderr in schema.ts (previously
silent) and logs the actual rejection in the test before failing, so
the next CI run tells us what is actually happening instead of us
guessing again.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nRJf8FVnwdjmSwgBt7tuX

* diag: trace schema worker startup step by step

Prior diagnostic showed no error/exit event ever fires for the real
schema.test.ts worker on CI - it just silently times out, meaning the
worker either never starts, or starts and hangs somewhere before
registering the message handler, with a code-0 exit event we were not
logging.

Switches schema-worker.ts to dynamic imports with a log after each
step (isMainThread/parentPort, ajv import, protocol import, Ajv
construction, handler registration, message receipt), adds
uncaughtException/unhandledRejection handlers, and logs the worker's
"online" event and every exit code (not just nonzero) on the parent
side. Confirmed locally the full sequence logs and the test passes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nRJf8FVnwdjmSwgBt7tuX

* fix: stop leaking a mock.module Worker across test files

Root cause, confirmed with a minimal local repro: bun 1.4.2's
mock.restore() does not actually undo mock.module("node:worker_threads",
...) for other test files sharing the same bun test process. Once
schema-worker-lineage.test.ts mocked node:worker_threads to return a
FakeWorker, schema.test.ts's plain "./schema.js" import of the real
Worker silently resolved to that FakeWorker instead - a class that
never emits online/message/error, so every validateJsonBounded() call
just sat there until our own internal timeout fired. That is why every
prior fix (longer timeouts, dropping the tsx execArgv) failed
identically: the worker was never real, so no amount of waiting or
loader changes could help. It only reproduced on the GitHub Actions
runner because import/module-cache ordering between the two test files
happened to differ there; a standalone repro (two files, one mocking
node:worker_threads and restoring, the other freshly importing it
after) reproduces the same leak locally.

Fixes this at the root instead of routing around it: schema.ts now
constructs its worker through an overridable factory
(setWorkerFactory), so schema-worker-lineage.test.ts can inject its
FakeWorker with a plain reassignment scoped to its own
"./schema.ts?worker-lineage" module instance, never touching bun's
global module registry. Removes mock.module/mock.restore entirely from
that test. Reverts the temporary diagnostic logging from the last two
commits now that the cause is known. Verified 5x locally and 3x in a
Linux bun 1.4.2 container.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nRJf8FVnwdjmSwgBt7tuX

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
No file changes — master already contains equivalent content from a
prior sync. This merge commit only records the shared ancestry so
future syncs diff cleanly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
feat: organize R2 asset keys by organization and project
* feat: add project appointments and asset management

* fix: refresh activity caches after appointment changes

* test: use Prisma connection for appointment lock races
* feat: replace public upload workflows with asset resources

* fix: keep database context out of browser bundles
@vercel

vercel Bot commented Sep 14, 2026

Copy link
Copy Markdown

@romanbsd is attempting to deploy a commit to the Comp AI - PoC Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions
github-actions Bot changed the base branch from release to main September 14, 2026 13:04
@github-actions

Copy link
Copy Markdown
Contributor

Retargeted this onto main.

release is the default branch so that a plain clone runs the last tagged release, but nothing merges into it — it is fast-forwarded onto the tag by the Release workflow and that is all. Changes go to main, and reach release when a release is cut.

Nothing is wrong with your branch. If the diff now shows commits that are already on main, rebase and force-push:

git fetch origin main
git rebase origin/main
git push --force-with-lease

@romanbsd romanbsd closed this Sep 14, 2026
@romanbsd
romanbsd deleted the bugfix/upload branch September 14, 2026 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants