9d8ce7c325
**Version:** `twenty-partners@1.3.2` (patch — internal refactor, no
visible behavior change)
## What & why
Reorganizes the `twenty-partners` SDK app from a flat, type-first layout
(`src/{objects,fields,views,logic-functions,front-components,…}`) into a
**vertical-slice** layout under `src/modules/<domain>/<feature>/`. Files
that
change together now live together; each SDK entrypoint is a thin
discoverable
shim over a service + graphql-ops + mapper/connector layer.
This is a pure structural refactor — **no object, field, view, enum,
logic
function, trigger, role, or application variable changed.**
## Final layout
```
src/modules/
shared/ http · services · graphql · utils · front-components · navigation-menu-items (cross-domain nav folders)
opportunity/ fields·view-fields·views·navigation-menu-items·page-layouts·constants + intake/ + matching/
partner/ objects·fields·constants·utils + directory/ · self-service/ · marketplace/ · application-intake/ (Discord connector/)
application/ objects·fields·views·navigation-menu-items·page-layouts + services · graphql
```
Every `defineLogicFunction` entrypoint is now a thin
`*.logic-function.ts`
(all < 40 lines) at its domain/feature root, delegating to a
`*.service.ts`;
graphql operations live in `graphql/{queries,mutations}/`, pure
transforms in
`mappers/`, outbound APIs (the Discord webhook) in `connector/`, pure
helpers
in `utils/`.
## Safety — the load-bearing invariant
The server diffs app primitives by `universalIdentifier`, so a
changed/dropped
UUID would drop-and-recreate the object on prod (data loss). This branch
holds
that line:
- **887 `universalIdentifier`s byte-identical** to the branch base
(every
relocation is a `git mv`; every extracted entrypoint keeps its original
UUID/name/trigger verbatim). Re-verified byte-identical across the
rebase.
- `yarn twenty dev --once` against a live workspace = **"No changes.
Twenty
metadata matches your manifest."**, confirmed idempotent on a second run
—
the whole refactor is a metadata no-op (zero create/delete/identity
change).
- Every extracted graphql op was verified **byte-identical** to its
original
(args, `first:` caps, pagination, selection sets), and the
partner-application
Discord embed's deliberate PII omission (no email / hourly rate) is
preserved.
## Rebased onto latest `main`
This branch is rebased onto `main` (`d20e5378fd`) and now carries main's
`twenty-sdk` / `twenty-client-sdk` **2.23.0-alpha.2** bump.
Note for reviewers: main had independently bumped this package to
`1.3.1`, so
the original `1.3.0 → 1.3.1` commit here was redundant and git dropped
it during
the rebase (`patch contents already upstream`) — with **no textual
conflict**,
since both sides wrote the same version string. The bump is therefore
now
**`1.3.2`**. The rebase touched only `package.json` and `yarn.lock`;
**every line
of refactored source is byte-identical** to the pre-rebase tree.
## Verification
All run on the rebased tree, against SDK `2.23.0-alpha.2` and a live
Twenty
server `v2.23.2`:
| Check | Result |
|---|---|
| `universalIdentifier` set | 887, byte-identical |
| `yarn twenty dev --once` | "No changes" (idempotent on re-run) |
| Typecheck | pass |
| `yarn lint` | 0 warnings, 0 errors (287 files) |
| `yarn test:unit` | 158/158 (23 files) |
| `yarn test:integration` | 45/45 (13 files) |
## Also in this PR
- **Architecture convention doc** — `AGENTS.md` (+ a one-line
`CLAUDE.md` pointer)
at the package root documents the vertical-slice conventions this
refactor
establishes: the layout, the dependency rule (`logic-function → service
→
graphql/connector`), file naming, connector = outbound-only (inbound
webhooks
are logic-functions), and the UUID invariant. It ships here so the doc
and the
structure it describes land together.
- **`modules/shared/`** dedup: the secret-guarded intake envelope, the
find-or-create-company/person helpers + their graphql ops, `collectAll`
pagination, `http-url`/`strip-markdown`/`is-non-empty-string` utils.
- **Vitest configs collapsed** into one `vitest.config.ts` with `unit` +
`integration` projects (`yarn test:unit` / `yarn test:integration`).
- Cross-domain nav folders (`pipeline-folder`,
`partner-workspace-folder`)
hoisted to `modules/shared/navigation-menu-items/`.
## Deferred (non-blocking, tracked follow-ups)
- Add direct unit tests for the shared `collectAll` / `isNonEmptyString`
utils
(currently covered indirectly).
- Move `submit-client-brief`'s zod schema out of its mapper file into
its own
schema file (mirroring the partner side).
- Route `stamp-partner-user-on-child` through the shared self-service
mutation ops.
- `find-partner-by-member.ts` is duplicated identically in the
`application` and
`self-service` domains; a candidate to hoist into `modules/shared/`.