@team-semicolon/semicolony-cli 4.18.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +200 -0
- package/NOTICE +8 -0
- package/README.md +152 -0
- package/dist/bundle.js +2887 -0
- package/dist/templates/launchd/ai.semicolony.host-signals-sidecar.plist +40 -0
- package/migrations/001_initial.sql +280 -0
- package/migrations/002_add_indexes.sql +11 -0
- package/migrations/003_add_fk.sql +32 -0
- package/migrations/004_session_count_trigger.sql +35 -0
- package/migrations/005_bot_workspace_audits.sql +16 -0
- package/migrations/006_bot_kb_subscriptions.sql +24 -0
- package/migrations/007_flatten_skill_names.sql +16 -0
- package/migrations/008_bot_workspace_files.sql +14 -0
- package/migrations/009_enforce_flat_skill_names.sql +53 -0
- package/migrations/010_bot_delegation.sql +27 -0
- package/migrations/011_drop_legacy_tables.sql +35 -0
- package/migrations/012_drop_bot_knowledge.sql +16 -0
- package/migrations/013_kb_workspace_domains.sql +88 -0
- package/migrations/014_timestamp_to_timestamptz.sql +33 -0
- package/migrations/015_kb_domain_enforcement.sql +83 -0
- package/migrations/016_ontology_redesign.sql +108 -0
- package/migrations/017_ontology_instance_model.sql +151 -0
- package/migrations/018_type_schema.sql +11 -0
- package/migrations/019_test_management.sql +69 -0
- package/migrations/020_bot_workspace_standard.sql +174 -0
- package/migrations/021_drop_dead_tables.sql +8 -0
- package/migrations/021_test_declarative.sql +19 -0
- package/migrations/022_bot_ontology_type.sql +38 -0
- package/migrations/022_kb_schema_enforcement.sql +77 -0
- package/migrations/023_decision_key_cleanup.ts +154 -0
- package/migrations/024_embedding_backfill.ts +137 -0
- package/migrations/025_kb_flat_keys.sql +33 -0
- package/migrations/026_drop_session_log.sql +19 -0
- package/migrations/027_kb_manager_skill.sql +22 -0
- package/migrations/028_skill_definitions_to_semicolony.sql +19 -0
- package/migrations/029_agents_citation_max_lines.sql +6 -0
- package/migrations/030_team_ontology.sql +54 -0
- package/migrations/031_gfp_tables.sql +101 -0
- package/migrations/031_kb_manager_domain_register.sql +12 -0
- package/migrations/032_gfp_skill_and_callback.sql +40 -0
- package/migrations/032_kebab_case_keys.sql +33 -0
- package/migrations/033_skill_workspace_rules.sql +10 -0
- package/migrations/034_current_to_date_keys.sql +13 -0
- package/migrations/034_current_to_date_keys.ts +104 -0
- package/migrations/035_bot_budgets.sql +51 -0
- package/migrations/036_gfp_stitch_design.sql +35 -0
- package/migrations/037_gfp_qa_sections.sql +13 -0
- package/migrations/038_gfp_phase_split.sql +26 -0
- package/migrations/039_meeting_audio_data.sql +2 -0
- package/migrations/040_bot_commitments.sql +68 -0
- package/migrations/041_palette_previews.sql +13 -0
- package/migrations/042_gfp_parallel_tracks.sql +37 -0
- package/migrations/043_blocker_key.sql +13 -0
- package/migrations/044_gfp_stitch_screenshots.sql +9 -0
- package/migrations/045_service_table_rename_and_projection.sql +150 -0
- package/migrations/046_service_ops_tables.sql +75 -0
- package/migrations/047_update_gfp_manager_skill.sql +16 -0
- package/migrations/048_service_migration_skill.sql +23 -0
- package/migrations/049_service_features.sql +39 -0
- package/migrations/050_service_kpi_action_items.sql +87 -0
- package/migrations/051_update_service_migration_skill_prompt.sql +9 -0
- package/migrations/052_feature_iteration_link.sql +11 -0
- package/migrations/052_services_table_rename.sql +149 -0
- package/migrations/053_feature_discovery.sql +47 -0
- package/migrations/054_deploy_verification.sql +17 -0
- package/migrations/055_feature_lifecycle.sql +37 -0
- package/migrations/056_service_incident_schema.sql +16 -0
- package/migrations/057_decision_date_to_metadata.ts +173 -0
- package/migrations/058_incubator_kb_schema.sql +8 -0
- package/migrations/059_incubator_sessions.sql +29 -0
- package/migrations/060_skill_reference_files.sql +8 -0
- package/migrations/061_cron_trigger_bridge.sql +7 -0
- package/migrations/062_bot_slack_profiles.sql +21 -0
- package/migrations/063_rename_gfp_skills.sql +7 -0
- package/migrations/064_bot_cost_log.sql +11 -0
- package/migrations/065_hub_spoke_orchestration.sql +35 -0
- package/migrations/066_cost_log_commitment.sql +9 -0
- package/migrations/067_module_ontology_type.sql +44 -0
- package/migrations/068_migrate_incubator_data.sql +32 -0
- package/migrations/069_action_items_sot.sql +156 -0
- package/migrations/069_cost_log_tokens.sql +45 -0
- package/migrations/070_services_sot_columns.sql +78 -0
- package/migrations/071_cleanup_deprecated_service_kb.sql +38 -0
- package/migrations/072_incubator_heartbeat.sql +12 -0
- package/migrations/072_service_role_schema.sql +57 -0
- package/migrations/073_service_type_and_platform.sql +8 -0
- package/migrations/074_schema_ref_type.sql +16 -0
- package/migrations/075_routing_delegation.sql +34 -0
- package/migrations/076_meeting_service_link.sql +5 -0
- package/migrations/077_agents_ontology_type.sql +93 -0
- package/migrations/078_incubator_agent.sql +45 -0
- package/migrations/079_drop_audio_blob_url.sql +4 -0
- package/migrations/080_kb_metadata_indexing.sql +9 -0
- package/migrations/081_person_unification.sql +41 -0
- package/migrations/082_discord_channel.sql +3 -0
- package/migrations/084_deprecate_kpi_metrics_table.sql +5 -0
- package/migrations/085_meeting_target_domain.sql +37 -0
- package/migrations/086_skill_routing_new_skills.sql +23 -0
- package/migrations/087_skill_routing_second_opinion.sql +8 -0
- package/migrations/088_meeting_notion_sync.sql +10 -0
- package/migrations/089_bot_commitments_dedup.sql +17 -0
- package/migrations/090_incubator_discord_guild.sql +8 -0
- package/migrations/091_drop_deprecated_gfp_kpi_views.sql +65 -0
- package/migrations/092_ontology_channel_mapping.sql +28 -0
- package/migrations/093_update_bot_workspace_paths.sql +15 -0
- package/migrations/094_cron_run_tracking.sql +28 -0
- package/migrations/095_drop_bot_cron_runs.sql +7 -0
- package/migrations/096_kb_pipeline_keys.sql +66 -0
- package/migrations/097_drop_empty_service_tables.sql +83 -0
- package/migrations/098_migrate_features_materials_drop.sql +119 -0
- package/migrations/099_migrate_sections_drop.sql +52 -0
- package/migrations/099_seed_cron_poller_tick.sql +14 -0
- package/migrations/100_migrate_services_drop.sql +57 -0
- package/migrations/101_drop_services.sql +5 -0
- package/migrations/102_cost_log_session_dedup.sql +13 -0
- package/migrations/103_board.sql +57 -0
- package/migrations/104_agent_factory.sql +284 -0
- package/migrations/105_kb_notify.sql +44 -0
- package/migrations/106_office_id_agents_commands.sql +73 -0
- package/migrations/107_agent_service_credentials.sql +79 -0
- package/migrations/108_drop_l2_ontology_seeds.sql +16 -0
- package/migrations/109_generic_ontology_descriptions.sql +21 -0
- package/migrations/110_kb_manager_skill_l2_cleanup.sql +34 -0
- package/migrations/111_drop_l2_team_ontology_seeds.sql +20 -0
- package/migrations/112_fix_pipeline_schema_and_role_trigger.sql +83 -0
- package/migrations/113_kb_history.sql +53 -0
- package/migrations/114_runtime_target_columns.sql +26 -0
- package/migrations/115_runtime_source_columns.sql +52 -0
- package/migrations/116_commitment_pattern_health.sql +81 -0
- package/migrations/117_commitment_pattern_alert_claims.sql +33 -0
- package/migrations/118_retire_semiclaw_semicolonybot_alias.sql +30 -0
- package/migrations/119_commitment_events.sql +51 -0
- package/migrations/120_host_signals.sql +51 -0
- package/migrations/121_agent_spec_derived_runtime_metadata.sql +68 -0
- package/migrations/122_agent_spec_derived_fk_policy.sql +18 -0
- package/migrations/123_agent_spec_projection_skip_targets.sql +24 -0
- package/migrations/124_bot_commitments_notify.sql +26 -0
- package/migrations/125_agent_personas.sql +36 -0
- package/migrations/128_entity_relations.sql +125 -0
- package/migrations/129_kb_multitenant_gateway.sql +86 -0
- package/migrations/130_jewelry_relation_types.sql +36 -0
- package/migrations/131_concierge_requests.sql +38 -0
- package/migrations/132_kb_supersession.sql +27 -0
- package/migrations/133_kb_claims.sql +52 -0
- package/migrations/134_migration_registry.sql +18 -0
- package/migrations/135_sc_roles.sql +102 -0
- package/migrations/136_runtime_tenant_columns.sql +71 -0
- package/migrations/137_runtime_backfill_team_semicolon.sql +131 -0
- package/migrations/138_runtime_constraints_not_valid.sql +56 -0
- package/migrations/139_tenant_vms.sql +31 -0
- package/migrations/140_fleet_slots.sql +23 -0
- package/migrations/141_provisioning_jobs.sql +29 -0
- package/migrations/142_rls_enable_semicolony.sql +129 -0
- package/migrations/143_rls_enable_public.sql +54 -0
- package/migrations/144_worker_device_registry.sql +211 -0
- package/migrations/145_workspace_profile_workstation_policy.sql +39 -0
- package/migrations/146_worker_profile_repo_scope.sql +24 -0
- package/migrations/147_worker_profile_semo_ops_repo_rename.sql +18 -0
- package/migrations/148_momo_runtime_convergence.sql +92 -0
- package/migrations/README.md +88 -0
- package/migrations-sqlite/kb/001_initial.sql +56 -0
- package/migrations-sqlite/ops/001_initial.sql +53 -0
- package/migrations-sqlite/ops/002_action_items.sql +48 -0
- package/package.json +78 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!--
|
|
3
|
+
SemiColony host-signals sidecar — pushes pgrep/PID/auth-profile signals to semicolony.host_signals.
|
|
4
|
+
|
|
5
|
+
Spec: KB semicolony decision/dashboard-host-signals-sidecar-2026-05-07
|
|
6
|
+
Action item: 4ddac18f
|
|
7
|
+
|
|
8
|
+
Install:
|
|
9
|
+
cp packages/cli/templates/launchd/ai.semicolony.host-signals-sidecar.plist \
|
|
10
|
+
~/Library/LaunchAgents/
|
|
11
|
+
launchctl load ~/Library/LaunchAgents/ai.semicolony.host-signals-sidecar.plist
|
|
12
|
+
|
|
13
|
+
Verify:
|
|
14
|
+
launchctl list | grep host-signals
|
|
15
|
+
semicolony host-signals show --limit 20
|
|
16
|
+
|
|
17
|
+
Polling: every 90 seconds (StartInterval). 5-minute dashboard freshness window
|
|
18
|
+
means missing 3 cycles → stale_count increments → daemon detection alert.
|
|
19
|
+
-->
|
|
20
|
+
<plist version="1.0">
|
|
21
|
+
<dict>
|
|
22
|
+
<key>Label</key><string>ai.semicolony.host-signals-sidecar</string>
|
|
23
|
+
<key>ProgramArguments</key>
|
|
24
|
+
<array>
|
|
25
|
+
<string>/usr/local/bin/semicolony</string>
|
|
26
|
+
<string>host-signals</string>
|
|
27
|
+
<string>push</string>
|
|
28
|
+
<string>--quiet</string>
|
|
29
|
+
</array>
|
|
30
|
+
<key>StartInterval</key><integer>90</integer>
|
|
31
|
+
<key>StandardOutPath</key><string>/Users/reus/.semicolony/logs/host-signals-sidecar.log</string>
|
|
32
|
+
<key>StandardErrorPath</key><string>/Users/reus/.semicolony/logs/host-signals-sidecar.log</string>
|
|
33
|
+
<key>EnvironmentVariables</key>
|
|
34
|
+
<dict>
|
|
35
|
+
<key>HOME</key><string>/Users/reus</string>
|
|
36
|
+
<key>PATH</key><string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
37
|
+
</dict>
|
|
38
|
+
<key>RunAtLoad</key><true/>
|
|
39
|
+
</dict>
|
|
40
|
+
</plist>
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
-- 001_initial.sql
|
|
2
|
+
-- 기존 semicolony 스키마 문서화 (모든 테이블은 이미 존재)
|
|
3
|
+
-- IF NOT EXISTS로 안전하게 작성 — 새 환경에서도 적용 가능
|
|
4
|
+
|
|
5
|
+
CREATE SCHEMA IF NOT EXISTS semicolony;
|
|
6
|
+
|
|
7
|
+
-- pgvector
|
|
8
|
+
CREATE EXTENSION IF NOT EXISTS vector;
|
|
9
|
+
|
|
10
|
+
-- ============================================================
|
|
11
|
+
-- 1. skills
|
|
12
|
+
-- ============================================================
|
|
13
|
+
CREATE TABLE IF NOT EXISTS semicolony.skills (
|
|
14
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
15
|
+
name VARCHAR(100) NOT NULL UNIQUE,
|
|
16
|
+
display_name VARCHAR(100),
|
|
17
|
+
description TEXT,
|
|
18
|
+
content TEXT NOT NULL,
|
|
19
|
+
category VARCHAR(50),
|
|
20
|
+
package VARCHAR(50) DEFAULT 'core',
|
|
21
|
+
is_active BOOLEAN DEFAULT true,
|
|
22
|
+
is_required BOOLEAN DEFAULT false,
|
|
23
|
+
install_order INT DEFAULT 100,
|
|
24
|
+
version VARCHAR(20) DEFAULT '1.0.0',
|
|
25
|
+
metadata JSONB DEFAULT '{}',
|
|
26
|
+
created_at TIMESTAMPTZ DEFAULT now(),
|
|
27
|
+
updated_at TIMESTAMPTZ DEFAULT now()
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
-- ============================================================
|
|
31
|
+
-- 2. commands
|
|
32
|
+
-- ============================================================
|
|
33
|
+
CREATE TABLE IF NOT EXISTS semicolony.commands (
|
|
34
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
35
|
+
name VARCHAR(100) NOT NULL,
|
|
36
|
+
folder VARCHAR(50) NOT NULL,
|
|
37
|
+
content TEXT NOT NULL,
|
|
38
|
+
description TEXT,
|
|
39
|
+
is_active BOOLEAN DEFAULT true,
|
|
40
|
+
created_at TIMESTAMPTZ DEFAULT now(),
|
|
41
|
+
updated_at TIMESTAMPTZ DEFAULT now(),
|
|
42
|
+
UNIQUE(folder, name)
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
-- ============================================================
|
|
46
|
+
-- 3. agents
|
|
47
|
+
-- ============================================================
|
|
48
|
+
CREATE TABLE IF NOT EXISTS semicolony.agents (
|
|
49
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
50
|
+
name VARCHAR(100) NOT NULL UNIQUE,
|
|
51
|
+
display_name VARCHAR(100),
|
|
52
|
+
content TEXT NOT NULL,
|
|
53
|
+
package VARCHAR(50) DEFAULT 'core',
|
|
54
|
+
is_active BOOLEAN DEFAULT true,
|
|
55
|
+
install_order INT DEFAULT 100,
|
|
56
|
+
created_at TIMESTAMPTZ DEFAULT now(),
|
|
57
|
+
updated_at TIMESTAMPTZ DEFAULT now()
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
-- ============================================================
|
|
61
|
+
-- 4. packages
|
|
62
|
+
-- ============================================================
|
|
63
|
+
CREATE TABLE IF NOT EXISTS semicolony.packages (
|
|
64
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
65
|
+
name VARCHAR(100) NOT NULL UNIQUE,
|
|
66
|
+
display_name VARCHAR(100),
|
|
67
|
+
description TEXT,
|
|
68
|
+
layer VARCHAR(50),
|
|
69
|
+
package_type VARCHAR(50),
|
|
70
|
+
version VARCHAR(20) DEFAULT '1.0.0',
|
|
71
|
+
is_active BOOLEAN DEFAULT true,
|
|
72
|
+
is_required BOOLEAN DEFAULT false,
|
|
73
|
+
install_order INT DEFAULT 100,
|
|
74
|
+
created_at TIMESTAMPTZ DEFAULT now(),
|
|
75
|
+
updated_at TIMESTAMPTZ DEFAULT now()
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
-- ============================================================
|
|
79
|
+
-- 5. knowledge_base (공통 KB)
|
|
80
|
+
-- ============================================================
|
|
81
|
+
CREATE TABLE IF NOT EXISTS semicolony.knowledge_base (
|
|
82
|
+
kb_id BIGSERIAL PRIMARY KEY,
|
|
83
|
+
domain VARCHAR(100) NOT NULL,
|
|
84
|
+
key VARCHAR(255) NOT NULL,
|
|
85
|
+
content TEXT NOT NULL,
|
|
86
|
+
embedding vector(1024),
|
|
87
|
+
metadata JSONB DEFAULT '{}',
|
|
88
|
+
version INT DEFAULT 1,
|
|
89
|
+
created_by VARCHAR(50),
|
|
90
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
91
|
+
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
92
|
+
UNIQUE(domain, key)
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
-- ============================================================
|
|
96
|
+
-- 6. bot_knowledge (봇별 KB)
|
|
97
|
+
-- ============================================================
|
|
98
|
+
CREATE TABLE IF NOT EXISTS semicolony.bot_knowledge (
|
|
99
|
+
id BIGSERIAL PRIMARY KEY,
|
|
100
|
+
bot_id VARCHAR(50) NOT NULL,
|
|
101
|
+
domain VARCHAR(100) NOT NULL,
|
|
102
|
+
key VARCHAR(255) NOT NULL,
|
|
103
|
+
content TEXT NOT NULL,
|
|
104
|
+
embedding vector(1024),
|
|
105
|
+
metadata JSONB DEFAULT '{}',
|
|
106
|
+
version INT DEFAULT 1,
|
|
107
|
+
synced_at TIMESTAMPTZ,
|
|
108
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
109
|
+
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
110
|
+
UNIQUE(bot_id, domain, key)
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
-- ============================================================
|
|
114
|
+
-- 7. ontology (도메인 스키마)
|
|
115
|
+
-- ============================================================
|
|
116
|
+
CREATE TABLE IF NOT EXISTS semicolony.ontology (
|
|
117
|
+
id BIGSERIAL PRIMARY KEY,
|
|
118
|
+
domain VARCHAR(100) NOT NULL UNIQUE,
|
|
119
|
+
schema JSONB NOT NULL,
|
|
120
|
+
description TEXT,
|
|
121
|
+
version INT DEFAULT 1,
|
|
122
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
123
|
+
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
-- ============================================================
|
|
127
|
+
-- 8. bot_status
|
|
128
|
+
-- ============================================================
|
|
129
|
+
CREATE TABLE IF NOT EXISTS semicolony.bot_status (
|
|
130
|
+
bot_id TEXT PRIMARY KEY,
|
|
131
|
+
name TEXT,
|
|
132
|
+
emoji TEXT,
|
|
133
|
+
role TEXT,
|
|
134
|
+
last_active TIMESTAMP,
|
|
135
|
+
session_count INTEGER DEFAULT 0,
|
|
136
|
+
workspace_path TEXT,
|
|
137
|
+
status TEXT,
|
|
138
|
+
synced_at TIMESTAMP DEFAULT NOW()
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
-- ============================================================
|
|
142
|
+
-- 9. bot_sessions
|
|
143
|
+
-- ============================================================
|
|
144
|
+
CREATE TABLE IF NOT EXISTS semicolony.bot_sessions (
|
|
145
|
+
bot_id TEXT NOT NULL,
|
|
146
|
+
session_key TEXT NOT NULL,
|
|
147
|
+
label TEXT,
|
|
148
|
+
kind TEXT,
|
|
149
|
+
chat_type TEXT,
|
|
150
|
+
last_activity TIMESTAMP,
|
|
151
|
+
message_count INTEGER DEFAULT 0,
|
|
152
|
+
synced_at TIMESTAMP DEFAULT NOW(),
|
|
153
|
+
PRIMARY KEY (bot_id, session_key)
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
-- ============================================================
|
|
157
|
+
-- 10. bot_cron_jobs
|
|
158
|
+
-- ============================================================
|
|
159
|
+
CREATE TABLE IF NOT EXISTS semicolony.bot_cron_jobs (
|
|
160
|
+
bot_id TEXT NOT NULL,
|
|
161
|
+
job_id TEXT NOT NULL,
|
|
162
|
+
name TEXT,
|
|
163
|
+
schedule JSONB,
|
|
164
|
+
enabled BOOLEAN DEFAULT TRUE,
|
|
165
|
+
last_run TIMESTAMP,
|
|
166
|
+
next_run TIMESTAMP,
|
|
167
|
+
session_target TEXT,
|
|
168
|
+
synced_at TIMESTAMP DEFAULT NOW(),
|
|
169
|
+
PRIMARY KEY (bot_id, job_id)
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
-- ============================================================
|
|
173
|
+
-- 11. bot_query_logs
|
|
174
|
+
-- ============================================================
|
|
175
|
+
CREATE TABLE IF NOT EXISTS semicolony.bot_query_logs (
|
|
176
|
+
id BIGSERIAL PRIMARY KEY,
|
|
177
|
+
bot_id TEXT NOT NULL,
|
|
178
|
+
user_id TEXT,
|
|
179
|
+
user_name TEXT,
|
|
180
|
+
channel TEXT,
|
|
181
|
+
channel_id TEXT,
|
|
182
|
+
thread_id TEXT,
|
|
183
|
+
query TEXT NOT NULL,
|
|
184
|
+
response TEXT,
|
|
185
|
+
model TEXT,
|
|
186
|
+
latency_ms INTEGER,
|
|
187
|
+
token_input INTEGER,
|
|
188
|
+
token_output INTEGER,
|
|
189
|
+
metadata JSONB DEFAULT '{}',
|
|
190
|
+
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
-- ============================================================
|
|
194
|
+
-- 기존 인덱스 (이미 존재하면 skip)
|
|
195
|
+
-- ============================================================
|
|
196
|
+
CREATE INDEX IF NOT EXISTS idx_semicolony_skills_name ON semicolony.skills(name);
|
|
197
|
+
CREATE INDEX IF NOT EXISTS idx_semicolony_skills_active ON semicolony.skills(is_active);
|
|
198
|
+
CREATE INDEX IF NOT EXISTS idx_semicolony_skills_category ON semicolony.skills(category);
|
|
199
|
+
CREATE INDEX IF NOT EXISTS idx_semicolony_commands_folder ON semicolony.commands(folder);
|
|
200
|
+
CREATE INDEX IF NOT EXISTS idx_semicolony_commands_active ON semicolony.commands(is_active);
|
|
201
|
+
CREATE INDEX IF NOT EXISTS idx_semicolony_agents_name ON semicolony.agents(name);
|
|
202
|
+
CREATE INDEX IF NOT EXISTS idx_semicolony_agents_active ON semicolony.agents(is_active);
|
|
203
|
+
CREATE INDEX IF NOT EXISTS idx_semicolony_packages_name ON semicolony.packages(name);
|
|
204
|
+
CREATE INDEX IF NOT EXISTS idx_semicolony_packages_layer ON semicolony.packages(layer);
|
|
205
|
+
CREATE INDEX IF NOT EXISTS idx_semicolony_packages_active ON semicolony.packages(is_active);
|
|
206
|
+
CREATE INDEX IF NOT EXISTS idx_kb_domain ON semicolony.knowledge_base(domain);
|
|
207
|
+
CREATE INDEX IF NOT EXISTS idx_kb_created_by ON semicolony.knowledge_base(created_by);
|
|
208
|
+
CREATE INDEX IF NOT EXISTS idx_kb_updated_at ON semicolony.knowledge_base(updated_at DESC);
|
|
209
|
+
CREATE INDEX IF NOT EXISTS idx_kb_embedding ON semicolony.knowledge_base USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64);
|
|
210
|
+
CREATE INDEX IF NOT EXISTS idx_botk_bot_id ON semicolony.bot_knowledge(bot_id);
|
|
211
|
+
CREATE INDEX IF NOT EXISTS idx_botk_domain ON semicolony.bot_knowledge(bot_id, domain);
|
|
212
|
+
CREATE INDEX IF NOT EXISTS idx_botk_updated_at ON semicolony.bot_knowledge(updated_at DESC);
|
|
213
|
+
CREATE INDEX IF NOT EXISTS idx_botk_embedding ON semicolony.bot_knowledge USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64);
|
|
214
|
+
CREATE INDEX IF NOT EXISTS idx_bot_status_synced_at ON semicolony.bot_status(synced_at);
|
|
215
|
+
CREATE INDEX IF NOT EXISTS idx_bot_sessions_bot_id ON semicolony.bot_sessions(bot_id);
|
|
216
|
+
CREATE INDEX IF NOT EXISTS idx_bot_sessions_last_activity ON semicolony.bot_sessions(last_activity DESC);
|
|
217
|
+
CREATE INDEX IF NOT EXISTS idx_bot_cron_jobs_bot_id ON semicolony.bot_cron_jobs(bot_id);
|
|
218
|
+
CREATE INDEX IF NOT EXISTS idx_bot_cron_jobs_next_run ON semicolony.bot_cron_jobs(next_run);
|
|
219
|
+
|
|
220
|
+
-- ============================================================
|
|
221
|
+
-- Helper: updated_at trigger function
|
|
222
|
+
-- ============================================================
|
|
223
|
+
CREATE OR REPLACE FUNCTION semicolony.update_updated_at()
|
|
224
|
+
RETURNS TRIGGER AS $$
|
|
225
|
+
BEGIN
|
|
226
|
+
NEW.updated_at = NOW();
|
|
227
|
+
NEW.version = COALESCE(OLD.version, 0) + 1;
|
|
228
|
+
RETURN NEW;
|
|
229
|
+
END;
|
|
230
|
+
$$ LANGUAGE plpgsql;
|
|
231
|
+
|
|
232
|
+
DO $$
|
|
233
|
+
BEGIN
|
|
234
|
+
IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'trg_kb_updated_at') THEN
|
|
235
|
+
CREATE TRIGGER trg_kb_updated_at BEFORE UPDATE ON semicolony.knowledge_base
|
|
236
|
+
FOR EACH ROW EXECUTE FUNCTION semicolony.update_updated_at();
|
|
237
|
+
END IF;
|
|
238
|
+
IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'trg_botk_updated_at') THEN
|
|
239
|
+
CREATE TRIGGER trg_botk_updated_at BEFORE UPDATE ON semicolony.bot_knowledge
|
|
240
|
+
FOR EACH ROW EXECUTE FUNCTION semicolony.update_updated_at();
|
|
241
|
+
END IF;
|
|
242
|
+
IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'trg_onto_updated_at') THEN
|
|
243
|
+
CREATE TRIGGER trg_onto_updated_at BEFORE UPDATE ON semicolony.ontology
|
|
244
|
+
FOR EACH ROW EXECUTE FUNCTION semicolony.update_updated_at();
|
|
245
|
+
END IF;
|
|
246
|
+
END $$;
|
|
247
|
+
|
|
248
|
+
-- ============================================================
|
|
249
|
+
-- Helper functions
|
|
250
|
+
-- ============================================================
|
|
251
|
+
CREATE OR REPLACE FUNCTION semicolony.get_active_skills()
|
|
252
|
+
RETURNS TABLE (
|
|
253
|
+
name VARCHAR(100),
|
|
254
|
+
content TEXT,
|
|
255
|
+
category VARCHAR(50),
|
|
256
|
+
install_order INT
|
|
257
|
+
) AS $$
|
|
258
|
+
BEGIN
|
|
259
|
+
RETURN QUERY
|
|
260
|
+
SELECT s.name, s.content, s.category, s.install_order
|
|
261
|
+
FROM semicolony.skills s
|
|
262
|
+
WHERE s.is_active = true
|
|
263
|
+
ORDER BY s.install_order;
|
|
264
|
+
END;
|
|
265
|
+
$$ LANGUAGE plpgsql;
|
|
266
|
+
|
|
267
|
+
CREATE OR REPLACE FUNCTION semicolony.get_skill_count_by_category()
|
|
268
|
+
RETURNS TABLE (
|
|
269
|
+
category VARCHAR(50),
|
|
270
|
+
count BIGINT
|
|
271
|
+
) AS $$
|
|
272
|
+
BEGIN
|
|
273
|
+
RETURN QUERY
|
|
274
|
+
SELECT s.category, COUNT(*)::BIGINT
|
|
275
|
+
FROM semicolony.skills s
|
|
276
|
+
WHERE s.is_active = true
|
|
277
|
+
GROUP BY s.category
|
|
278
|
+
ORDER BY MIN(s.install_order);
|
|
279
|
+
END;
|
|
280
|
+
$$ LANGUAGE plpgsql;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
-- 002_add_indexes.sql
|
|
2
|
+
-- P1-2: 누락된 성능 인덱스 추가
|
|
3
|
+
|
|
4
|
+
-- bot_status.status 필터용
|
|
5
|
+
CREATE INDEX IF NOT EXISTS idx_bot_status_status ON semicolony.bot_status(status);
|
|
6
|
+
|
|
7
|
+
-- bot_query_logs 조회 최적화
|
|
8
|
+
CREATE INDEX IF NOT EXISTS idx_bql_bot_id ON semicolony.bot_query_logs(bot_id);
|
|
9
|
+
CREATE INDEX IF NOT EXISTS idx_bql_user_id ON semicolony.bot_query_logs(user_id);
|
|
10
|
+
CREATE INDEX IF NOT EXISTS idx_bql_created_at ON semicolony.bot_query_logs(created_at DESC);
|
|
11
|
+
CREATE INDEX IF NOT EXISTS idx_bql_channel_id ON semicolony.bot_query_logs(channel_id);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
-- 003_add_fk.sql
|
|
2
|
+
-- P1-3: FK 제약 추가
|
|
3
|
+
|
|
4
|
+
-- bot_sessions.bot_id → bot_status.bot_id
|
|
5
|
+
DO $$
|
|
6
|
+
BEGIN
|
|
7
|
+
IF NOT EXISTS (
|
|
8
|
+
SELECT 1 FROM information_schema.table_constraints
|
|
9
|
+
WHERE constraint_name = 'fk_sessions_bot'
|
|
10
|
+
AND table_schema = 'semicolony'
|
|
11
|
+
) THEN
|
|
12
|
+
ALTER TABLE semicolony.bot_sessions
|
|
13
|
+
ADD CONSTRAINT fk_sessions_bot
|
|
14
|
+
FOREIGN KEY (bot_id) REFERENCES semicolony.bot_status(bot_id) ON DELETE CASCADE;
|
|
15
|
+
END IF;
|
|
16
|
+
END $$;
|
|
17
|
+
|
|
18
|
+
-- bot_cron_jobs.bot_id → bot_status.bot_id
|
|
19
|
+
DO $$
|
|
20
|
+
BEGIN
|
|
21
|
+
IF NOT EXISTS (
|
|
22
|
+
SELECT 1 FROM information_schema.table_constraints
|
|
23
|
+
WHERE constraint_name = 'fk_cron_jobs_bot'
|
|
24
|
+
AND table_schema = 'semicolony'
|
|
25
|
+
) THEN
|
|
26
|
+
ALTER TABLE semicolony.bot_cron_jobs
|
|
27
|
+
ADD CONSTRAINT fk_cron_jobs_bot
|
|
28
|
+
FOREIGN KEY (bot_id) REFERENCES semicolony.bot_status(bot_id) ON DELETE CASCADE;
|
|
29
|
+
END IF;
|
|
30
|
+
END $$;
|
|
31
|
+
|
|
32
|
+
-- bot_query_logs는 FK 제외 — 로그 테이블은 참조 무결성보다 적재 안정성 우선
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
-- 004_session_count_trigger.sql
|
|
2
|
+
-- P0-3: session_count 경쟁 조건 해결
|
|
3
|
+
-- bot_sessions INSERT/DELETE 시 bot_status.session_count 자동 갱신 트리거
|
|
4
|
+
|
|
5
|
+
CREATE OR REPLACE FUNCTION semicolony.update_session_count()
|
|
6
|
+
RETURNS TRIGGER AS $$
|
|
7
|
+
DECLARE
|
|
8
|
+
target_bot_id TEXT;
|
|
9
|
+
BEGIN
|
|
10
|
+
IF TG_OP = 'DELETE' THEN
|
|
11
|
+
target_bot_id := OLD.bot_id;
|
|
12
|
+
ELSE
|
|
13
|
+
target_bot_id := NEW.bot_id;
|
|
14
|
+
END IF;
|
|
15
|
+
|
|
16
|
+
UPDATE semicolony.bot_status
|
|
17
|
+
SET session_count = (
|
|
18
|
+
SELECT COUNT(*) FROM semicolony.bot_sessions WHERE bot_id = target_bot_id
|
|
19
|
+
)
|
|
20
|
+
WHERE bot_id = target_bot_id;
|
|
21
|
+
|
|
22
|
+
IF TG_OP = 'DELETE' THEN
|
|
23
|
+
RETURN OLD;
|
|
24
|
+
ELSE
|
|
25
|
+
RETURN NEW;
|
|
26
|
+
END IF;
|
|
27
|
+
END;
|
|
28
|
+
$$ LANGUAGE plpgsql;
|
|
29
|
+
|
|
30
|
+
-- 기존 트리거 있으면 교체
|
|
31
|
+
DROP TRIGGER IF EXISTS trg_session_count ON semicolony.bot_sessions;
|
|
32
|
+
|
|
33
|
+
CREATE TRIGGER trg_session_count
|
|
34
|
+
AFTER INSERT OR DELETE ON semicolony.bot_sessions
|
|
35
|
+
FOR EACH ROW EXECUTE FUNCTION semicolony.update_session_count();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
-- Bot Workspace Audits
|
|
2
|
+
-- 봇 워크스페이스 표준 구조 compliance 감사 결과 저장
|
|
3
|
+
|
|
4
|
+
CREATE TABLE IF NOT EXISTS semicolony.bot_workspace_audits (
|
|
5
|
+
id BIGSERIAL PRIMARY KEY,
|
|
6
|
+
bot_id TEXT NOT NULL,
|
|
7
|
+
run_id TEXT NOT NULL,
|
|
8
|
+
rating TEXT NOT NULL, -- 'GOOD' | 'NEEDS-WORK' | 'POOR'
|
|
9
|
+
score INT NOT NULL DEFAULT 0, -- 0-100
|
|
10
|
+
checks JSONB NOT NULL, -- [{ name, passed, detail }]
|
|
11
|
+
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
CREATE INDEX IF NOT EXISTS idx_bwa_bot_id ON semicolony.bot_workspace_audits(bot_id);
|
|
15
|
+
CREATE INDEX IF NOT EXISTS idx_bwa_run_id ON semicolony.bot_workspace_audits(run_id);
|
|
16
|
+
CREATE INDEX IF NOT EXISTS idx_bwa_created_at ON semicolony.bot_workspace_audits(created_at DESC);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
-- 006: Bot KB Subscriptions
|
|
2
|
+
-- 봇별 KB 도메인 구독 + 변경 다이제스트 워터마크
|
|
3
|
+
|
|
4
|
+
CREATE TABLE IF NOT EXISTS semicolony.bot_kb_subscriptions (
|
|
5
|
+
bot_id VARCHAR(50) NOT NULL,
|
|
6
|
+
domain VARCHAR(100) NOT NULL,
|
|
7
|
+
last_synced_at TIMESTAMPTZ DEFAULT '1970-01-01T00:00:00Z',
|
|
8
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
9
|
+
PRIMARY KEY (bot_id, domain)
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
CREATE INDEX IF NOT EXISTS idx_bot_kb_subs_bot_id
|
|
13
|
+
ON semicolony.bot_kb_subscriptions(bot_id);
|
|
14
|
+
|
|
15
|
+
-- Seed: 봇별 구독 도메인
|
|
16
|
+
INSERT INTO semicolony.bot_kb_subscriptions (bot_id, domain) VALUES
|
|
17
|
+
('semiclaw', 'team'), ('semiclaw', 'project'), ('semiclaw', 'decision'), ('semiclaw', 'process'), ('semiclaw', 'infra'),
|
|
18
|
+
('workclaw', 'team'), ('workclaw', 'project'), ('workclaw', 'decision'), ('workclaw', 'process'),
|
|
19
|
+
('reviewclaw', 'team'), ('reviewclaw', 'project'), ('reviewclaw', 'decision'),
|
|
20
|
+
('planclaw', 'team'), ('planclaw', 'project'), ('planclaw', 'decision'), ('planclaw', 'process'),
|
|
21
|
+
('designclaw', 'team'), ('designclaw', 'project'), ('designclaw', 'decision'),
|
|
22
|
+
('infraclaw', 'team'), ('infraclaw', 'infra'), ('infraclaw', 'decision'),
|
|
23
|
+
('growthclaw', 'team'), ('growthclaw', 'project'), ('growthclaw', 'decision')
|
|
24
|
+
ON CONFLICT DO NOTHING;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
-- 007_flatten_skill_names.sql
|
|
2
|
+
-- Flat skill naming: botId/skillName → skillName + metadata.bot_ids
|
|
3
|
+
--
|
|
4
|
+
-- 1. metadata.bot_id (string) → metadata.bot_ids (array) 변환
|
|
5
|
+
-- 2. name에서 botId/ 프리픽스 제거
|
|
6
|
+
|
|
7
|
+
-- Step 1: metadata.bot_id → metadata.bot_ids 배열로 변환
|
|
8
|
+
UPDATE skill_definitions
|
|
9
|
+
SET metadata = (metadata - 'bot_id') || jsonb_build_object('bot_ids', jsonb_build_array(metadata->>'bot_id'))
|
|
10
|
+
WHERE metadata ? 'bot_id';
|
|
11
|
+
|
|
12
|
+
-- Step 2: name에서 botId/ 프리픽스 제거
|
|
13
|
+
UPDATE skill_definitions
|
|
14
|
+
SET name = SUBSTRING(name FROM POSITION('/' IN name) + 1)
|
|
15
|
+
WHERE name LIKE '%/%'
|
|
16
|
+
AND office_id IS NULL;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
-- Bot workspace file storage for Dashboard DB-based access
|
|
2
|
+
-- Replaces local filesystem reads with DB queries
|
|
3
|
+
|
|
4
|
+
CREATE TABLE IF NOT EXISTS semicolony.bot_workspace_files (
|
|
5
|
+
bot_id TEXT NOT NULL,
|
|
6
|
+
file_path TEXT NOT NULL,
|
|
7
|
+
content TEXT NOT NULL,
|
|
8
|
+
file_size INTEGER,
|
|
9
|
+
file_hash TEXT, -- SHA-256, 변경 감지용
|
|
10
|
+
synced_at TIMESTAMPTZ DEFAULT NOW(),
|
|
11
|
+
PRIMARY KEY (bot_id, file_path)
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
CREATE INDEX IF NOT EXISTS idx_bwf_bot ON semicolony.bot_workspace_files(bot_id);
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
-- 009_enforce_flat_skill_names.sql
|
|
2
|
+
-- Enforce flat skill names (strip any remaining slashes)
|
|
3
|
+
-- Also add CHECK constraint to prevent future slashes
|
|
4
|
+
|
|
5
|
+
-- Step 1: flat 이름이 이미 존재하면 slash 버전의 metadata.bot_ids를 flat 버전에 병합 후 삭제
|
|
6
|
+
-- (slash 버전에만 있는 bot_ids를 보존)
|
|
7
|
+
WITH slash_skills AS (
|
|
8
|
+
SELECT id, name,
|
|
9
|
+
SUBSTRING(name FROM POSITION('/' IN name) + 1) AS flat_name,
|
|
10
|
+
metadata
|
|
11
|
+
FROM skill_definitions
|
|
12
|
+
WHERE name LIKE '%/%' AND office_id IS NULL
|
|
13
|
+
),
|
|
14
|
+
has_flat AS (
|
|
15
|
+
SELECT s.id AS slash_id, s.flat_name, s.metadata AS slash_meta,
|
|
16
|
+
f.id AS flat_id, f.metadata AS flat_meta
|
|
17
|
+
FROM slash_skills s
|
|
18
|
+
JOIN skill_definitions f ON f.name = s.flat_name AND f.office_id IS NULL
|
|
19
|
+
)
|
|
20
|
+
-- Merge bot_ids from slash version into flat version
|
|
21
|
+
UPDATE skill_definitions f
|
|
22
|
+
SET metadata = CASE
|
|
23
|
+
WHEN f.metadata ? 'bot_ids' AND hf.slash_meta ? 'bot_ids'
|
|
24
|
+
THEN jsonb_set(f.metadata, '{bot_ids}',
|
|
25
|
+
(SELECT jsonb_agg(DISTINCT val)
|
|
26
|
+
FROM (
|
|
27
|
+
SELECT val FROM jsonb_array_elements(f.metadata->'bot_ids') val
|
|
28
|
+
UNION
|
|
29
|
+
SELECT val FROM jsonb_array_elements(hf.slash_meta->'bot_ids') val
|
|
30
|
+
) combined))
|
|
31
|
+
WHEN hf.slash_meta ? 'bot_ids'
|
|
32
|
+
THEN COALESCE(f.metadata, '{}'::jsonb) || jsonb_build_object('bot_ids', hf.slash_meta->'bot_ids')
|
|
33
|
+
ELSE f.metadata
|
|
34
|
+
END
|
|
35
|
+
FROM has_flat hf
|
|
36
|
+
WHERE f.id = hf.flat_id;
|
|
37
|
+
|
|
38
|
+
-- Step 2: Delete slash versions that have a flat counterpart
|
|
39
|
+
DELETE FROM skill_definitions
|
|
40
|
+
WHERE name LIKE '%/%'
|
|
41
|
+
AND office_id IS NULL
|
|
42
|
+
AND SUBSTRING(name FROM POSITION('/' IN name) + 1) IN (
|
|
43
|
+
SELECT name FROM skill_definitions WHERE name NOT LIKE '%/%' AND office_id IS NULL
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
-- Step 3: Rename remaining slash versions (no flat counterpart)
|
|
47
|
+
UPDATE skill_definitions
|
|
48
|
+
SET name = SUBSTRING(name FROM POSITION('/' IN name) + 1)
|
|
49
|
+
WHERE name LIKE '%/%' AND office_id IS NULL;
|
|
50
|
+
|
|
51
|
+
-- Step 4: Prevent future slashes
|
|
52
|
+
ALTER TABLE skill_definitions
|
|
53
|
+
ADD CONSTRAINT skill_name_no_slash CHECK (name NOT LIKE '%/%');
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
-- 010_bot_delegation.sql
|
|
2
|
+
-- Bot delegation matrix: who can delegate what to whom
|
|
3
|
+
|
|
4
|
+
CREATE TABLE IF NOT EXISTS semicolony.bot_delegation (
|
|
5
|
+
id SERIAL PRIMARY KEY,
|
|
6
|
+
from_bot_id TEXT NOT NULL,
|
|
7
|
+
to_bot_id TEXT NOT NULL,
|
|
8
|
+
delegation_type TEXT NOT NULL DEFAULT 'task',
|
|
9
|
+
domains TEXT[] NOT NULL DEFAULT '{}',
|
|
10
|
+
method TEXT NOT NULL DEFAULT 'github_issue',
|
|
11
|
+
channel TEXT,
|
|
12
|
+
max_roundtrips INT DEFAULT 5,
|
|
13
|
+
priority TEXT DEFAULT 'medium',
|
|
14
|
+
is_active BOOLEAN DEFAULT true,
|
|
15
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
16
|
+
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
17
|
+
UNIQUE (from_bot_id, to_bot_id, delegation_type)
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
-- Protocol metadata (structured version of PROTOCOL.md)
|
|
21
|
+
CREATE TABLE IF NOT EXISTS semicolony.bot_protocol (
|
|
22
|
+
id SERIAL PRIMARY KEY,
|
|
23
|
+
key TEXT NOT NULL UNIQUE,
|
|
24
|
+
value JSONB NOT NULL,
|
|
25
|
+
description TEXT,
|
|
26
|
+
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
27
|
+
);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
-- 011_drop_legacy_tables.sql
|
|
2
|
+
-- 레거시 정규화 테이블 정리: KB(domain='project')가 SoT로 확정됨
|
|
3
|
+
-- FK 의존관계 순서: 자식 → 부모
|
|
4
|
+
|
|
5
|
+
BEGIN;
|
|
6
|
+
|
|
7
|
+
-- Group A: 프로젝트 관리 계층 (KB domain='project'로 대체됨)
|
|
8
|
+
DROP TABLE IF EXISTS semicolony.kpi_snapshots;
|
|
9
|
+
DROP TABLE IF EXISTS semicolony.project_kpi;
|
|
10
|
+
DROP TABLE IF EXISTS semicolony.tasks; -- FK: projects, epics, sprints
|
|
11
|
+
DROP TABLE IF EXISTS semicolony.sprints; -- FK: projects
|
|
12
|
+
DROP TABLE IF EXISTS semicolony.epics; -- FK: projects
|
|
13
|
+
DROP TABLE IF EXISTS semicolony.projects; -- 루트 — KB가 SoT
|
|
14
|
+
|
|
15
|
+
-- Group B: 워크플로우 엔진 (생성만 되고 사용 안 됨)
|
|
16
|
+
DROP TABLE IF EXISTS semicolony.workflow_node_executions; -- FK: instances, nodes
|
|
17
|
+
DROP TABLE IF EXISTS semicolony.workflow_instances; -- FK: definitions, nodes
|
|
18
|
+
DROP TABLE IF EXISTS semicolony.workflow_nodes; -- FK: definitions
|
|
19
|
+
DROP TABLE IF EXISTS semicolony.workflow_definitions; -- 루트
|
|
20
|
+
|
|
21
|
+
-- Group C: 아카이브 코드에서만 참조 (mcp-server/_archived)
|
|
22
|
+
DROP TABLE IF EXISTS semicolony.sessions;
|
|
23
|
+
DROP TABLE IF EXISTS semicolony.interaction_logs;
|
|
24
|
+
DROP TABLE IF EXISTS semicolony.embedding_requests;
|
|
25
|
+
DROP TABLE IF EXISTS semicolony.user_facts;
|
|
26
|
+
DROP TABLE IF EXISTS semicolony.memory_stats;
|
|
27
|
+
DROP VIEW IF EXISTS semicolony.index_usage;
|
|
28
|
+
DROP TABLE IF EXISTS semicolony.audit_logs;
|
|
29
|
+
|
|
30
|
+
-- 마이그레이션 기록
|
|
31
|
+
INSERT INTO semicolony.schema_migrations (version)
|
|
32
|
+
VALUES ('011_drop_legacy_tables')
|
|
33
|
+
ON CONFLICT (version) DO NOTHING;
|
|
34
|
+
|
|
35
|
+
COMMIT;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
-- Migration 012: Drop bot_knowledge and bot_kb_subscriptions
|
|
2
|
+
-- bot_knowledge 데이터를 knowledge_base로 이관 후 테이블 DROP.
|
|
3
|
+
-- 봇 프라이빗 KB를 폐기하고 knowledge_base 단일 테이블로 통일.
|
|
4
|
+
|
|
5
|
+
-- 1. bot_knowledge → knowledge_base 이관 (중복 시 skip)
|
|
6
|
+
INSERT INTO semicolony.knowledge_base (domain, key, content, metadata, embedding, created_by)
|
|
7
|
+
SELECT domain, key, content, metadata, embedding, bot_id AS created_by
|
|
8
|
+
FROM semicolony.bot_knowledge
|
|
9
|
+
ON CONFLICT (domain, key) DO NOTHING;
|
|
10
|
+
|
|
11
|
+
-- 2. 테이블 DROP
|
|
12
|
+
DROP TABLE IF EXISTS semicolony.bot_knowledge;
|
|
13
|
+
DROP TABLE IF EXISTS semicolony.bot_kb_subscriptions;
|
|
14
|
+
|
|
15
|
+
-- 3. bot:* 온톨로지 제거 (봇 프라이빗 KB 폐기로 불필요)
|
|
16
|
+
DELETE FROM semicolony.ontology WHERE domain LIKE 'bot:%';
|