feat(git-sync): per-space 'Enable Git sync' toggle (Phase C, §7.1)

UI opt-in for git-sync, mirroring the existing sharing/comments settings pattern
(no new endpoint, no new mechanism; orchestrator read query untouched):
- UpdateSpaceDto.gitSyncEnabled?: boolean.
- SpaceRepo.updateGitSyncSettings: jsonb-merge into settings.gitSync.<key>
  (COALESCE || jsonb_build_object — never clobbers sibling sharing/comments);
  stored as a real jsonb boolean so the orchestrator's
  settings->'gitSync'->>'enabled' = 'true' matches.
- SpaceService.updateSpace handles the flag (audit diff) via the existing
  CASL-guarded space update path (Manage/Settings).
- client: Switch in edit-space-form (optimistic mutate + revert-on-error,
  readOnly-aware) + space types + 2 i18n keys.
- space.service.spec extended (calls updateGitSyncSettings; no-op when undefined).
tsc clean (server+client); jest src/core/space 4 pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
claude code agent 227
2026-06-21 15:42:52 +03:00
parent 44a0b08e52
commit 9a4895e7ef
7 changed files with 161 additions and 2 deletions

View File

@@ -111,6 +111,28 @@ export class SpaceRepo {
.executeTakeFirst();
}
async updateGitSyncSettings(
spaceId: string,
workspaceId: string,
prefKey: string,
prefValue: string | boolean,
trx?: KyselyTransaction,
) {
const db = dbOrTx(this.db, trx);
return db
.updateTable('spaces')
.set({
settings: sql`COALESCE(settings, '{}'::jsonb)
|| jsonb_build_object('gitSync', COALESCE(settings->'gitSync', '{}'::jsonb)
|| jsonb_build_object('${sql.raw(prefKey)}', ${sql.lit(prefValue)}))`,
updatedAt: new Date(),
})
.where('id', '=', spaceId)
.where('workspaceId', '=', workspaceId)
.returningAll()
.executeTakeFirst();
}
async updateCommentSettings(
spaceId: string,
workspaceId: string,