Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
# .env は絶対にコミットしないこと

# === Slack ===
SLACK_BOT_TOKEN=
SLACK_SIGNING_SECRET=
SLACK_APP_ID=
SLACK_BOT_TOKEN= # xoxb-... (OAuth & Permissions)
SLACK_APP_TOKEN= # xapp-... (Basic Information → App-Level Tokens → connections:write)
SLACK_APP_ID= # A0XXXXXXX (setup.sh で使用)
SLACK_SIGNING_SECRET= # 不要になりましたが念のため残す
SLACK_MENTOR_CHANNEL_ID=
SLACK_PROGRESS_CHANNEL_ID=

# === Database ===
DATABASE_URL=postgres://postgres:postgres@localhost:5432/kcl_support_hub
DATABASE_URL=postgres://postgres:postgres@localhost:5432/kcl_support_hub?sslmode=disable

# === AI (Bonsai / Ollama) ===
# ollama serve && ollama pull qwen2.5:7b を実行してから設定
Expand All @@ -34,7 +35,7 @@ ONYX_API_URL=
ONYX_API_KEY=

# === AWS ===
AWS_REGION=ap-northeast-1
AWS_REGION=us-east-1
# ローカル開発 (LocalStack) 用
AWS_ENDPOINT_URL=http://localhost:4566
AWS_ACCESS_KEY_ID=test
Expand Down
31 changes: 12 additions & 19 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ export

.PHONY: help \
up down logs \
init-sqs \
migrate migrate-down migrate-status \
dev-api dev-worker dev-web \
docs docs-build \
docs \
build \
slack-setup slack-manifest \
slack-manifest \
lint test \
setup

Expand All @@ -22,6 +23,7 @@ help:
@echo " make up Docker インフラ起動 (postgres + localstack)"
@echo " make down Docker インフラ停止"
@echo " make logs Docker ログ表示"
@echo " make init-sqs LocalStack SQS キュー作成 (up後に必要)"
@echo ""
@echo " DB"
@echo " make migrate マイグレーション実行"
Expand All @@ -33,20 +35,18 @@ help:
@echo " make dev-worker TypeScript Worker 起動"
@echo " make dev-web Next.js ダッシュボード起動 (port 3000)"
@echo " make docs ドキュメントサーバー起動 (port 4000)"
@echo " make docs-build ドキュメントを静的ファイルにビルド"
@echo ""
@echo " Slack"
@echo " make slack-setup URL=https://xxxx.ngrok-free.app"
@echo " Slash Commands + Interactivity URL を一括更新"
@echo " make slack-manifest manifest.json の内容を表示"
@echo " ※ Socket Mode 使用中のため ngrok / URL 設定不要"
@echo ""
@echo " ビルド / テスト"
@echo " make build 全サービスをビルド"
@echo " make lint 全サービスのリント"
@echo " make test 全サービスのテスト"
@echo ""
@echo " 初回セットアップ一括"
@echo " make setup up + migrate をまとめて実行"
@echo " make setup up + init-sqs + migrate をまとめて実行"
@echo ""

# -----------------------------------------------
Expand All @@ -55,6 +55,9 @@ help:
up:
docker compose -f infra/docker/compose.yml up -d

init-sqs:
docker exec docker-localstack-1 bash /etc/localstack/init/ready.d/init-localstack.sh

down:
docker compose -f infra/docker/compose.yml down

Expand Down Expand Up @@ -83,26 +86,17 @@ dev-worker:
cd apps/worker && pnpm dev

dev-web:
cd apps/web && pnpm dev
cd apps/web && PORT=3000 pnpm dev

# -----------------------------------------------
# ドキュメント
# -----------------------------------------------
docs:
cd docs-host && pnpm dev

docs-build:
cd docs-host && pnpm build
node docs-host/server.js

# -----------------------------------------------
# Slack
# -----------------------------------------------
slack-setup:
ifndef URL
$(error URLを指定してください: make slack-setup URL=https://xxxx.ngrok-free.app)
endif
./infra/slack/setup.sh "$(URL)"

slack-manifest:
@cat infra/slack/manifest.json

Expand Down Expand Up @@ -132,11 +126,10 @@ test:
setup: up
@echo "インフラ起動を待機中..."
@sleep 5
$(MAKE) init-sqs
$(MAKE) migrate
@echo ""
@echo "セットアップ完了。次のステップ:"
@echo " 1. make dev-api (別ターミナル)"
@echo " 2. make dev-worker (別ターミナル)"
@echo " 3. make dev-web (別ターミナル)"
@echo " 4. ngrok http 8080"
@echo " 5. make slack-setup URL=<ngrok URL>"
9 changes: 5 additions & 4 deletions apps/api/cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ func main() {
log.Fatalf("sqs init: %v", err)
}

// Start Slack Socket Mode in a background goroutine.
// Connects to Slack via WebSocket — no public URL required.
go slackhandler.RunSocketMode(cfg, sqlDB, sqsClient)

if !cfg.IsDev() {
gin.SetMode(gin.ReleaseMode)
}
Expand All @@ -46,13 +50,10 @@ func main() {
c.JSON(http.StatusOK, gin.H{"status": "ok"})
})

// Slack webhook routes
r.POST("/slack/commands", slackhandler.HandleSlashCommand(cfg, sqlDB))
r.POST("/slack/interactions", slackhandler.HandleInteraction(cfg, sqlDB, sqsClient))

// REST API routes for the dashboard
api := r.Group("/api")
{
api.GET("/hackathons", apihandler.HandleListHackathons(sqlDB))
api.GET("/questions", apihandler.HandleListQuestions(sqlDB))
api.GET("/questions/:id", apihandler.HandleGetQuestion(sqlDB))
api.GET("/progress", apihandler.HandleListProgress(sqlDB))
Expand Down
39 changes: 39 additions & 0 deletions apps/api/db/migrations/007_create_hackathons.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
-- +goose Up
CREATE TABLE hackathons (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
slug TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

ALTER TABLE teams
ADD COLUMN hackathon_id UUID REFERENCES hackathons (id),
ADD COLUMN slack_workspace_id TEXT;

INSERT INTO hackathons (id, slug, name)
VALUES (
'00000000-0000-0000-0000-000000000001',
'default-hackathon',
'Default Hackathon'
);

UPDATE teams
SET hackathon_id = '00000000-0000-0000-0000-000000000001'
WHERE hackathon_id IS NULL;

ALTER TABLE teams
ALTER COLUMN hackathon_id SET NOT NULL;

CREATE INDEX idx_teams_hackathon_id ON teams (hackathon_id);
CREATE INDEX idx_teams_slack_scope ON teams (slack_workspace_id, slack_channel_id);

-- +goose Down
DROP INDEX idx_teams_slack_scope;
DROP INDEX idx_teams_hackathon_id;

ALTER TABLE teams
DROP COLUMN slack_workspace_id,
DROP COLUMN hackathon_id;

DROP TABLE hackathons;
8 changes: 8 additions & 0 deletions apps/api/db/queries/hackathons.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- name: ListHackathons :many
SELECT
*
FROM
hackathons
ORDER BY
created_at ASC,
name ASC;
15 changes: 10 additions & 5 deletions apps/api/db/queries/progress.sql
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,25 @@ RETURNING

-- name: ListProgressLogs :many
SELECT
*
progress_logs.*
FROM
progress_logs
LEFT JOIN teams ON teams.id = progress_logs.team_id
WHERE
(
sqlc.narg (team_id)::uuid IS NULL
OR team_id = sqlc.narg (team_id)::uuid
OR progress_logs.team_id = sqlc.narg (team_id)::uuid
)
AND (
sqlc.narg (hackathon_id)::uuid IS NULL
OR teams.hackathon_id = sqlc.narg (hackathon_id)::uuid
)
ORDER BY
created_at DESC
progress_logs.created_at DESC
LIMIT
$2
sqlc.arg(page_limit)::int
OFFSET
$3;
sqlc.arg(page_offset)::int;

-- name: LatestProgressPerTeam :many
SELECT DISTINCT
Expand Down
15 changes: 10 additions & 5 deletions apps/api/db/queries/questions.sql
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,25 @@ WHERE

-- name: ListQuestions :many
SELECT
*
questions.*
FROM
questions
LEFT JOIN teams ON teams.id = questions.team_id
WHERE
(
sqlc.narg (status)::text IS NULL
OR status = sqlc.narg (status)
OR questions.status = sqlc.narg (status)::text
)
AND (
sqlc.narg (hackathon_id)::uuid IS NULL
OR teams.hackathon_id = sqlc.narg (hackathon_id)::uuid
)
ORDER BY
created_at DESC
questions.created_at DESC
LIMIT
$2
sqlc.arg(page_limit)::int
OFFSET
$3;
sqlc.arg(page_offset)::int;

-- name: UpdateQuestionStatus :exec
UPDATE questions
Expand Down
17 changes: 15 additions & 2 deletions apps/api/db/queries/teams.sql
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,27 @@ SELECT
*
FROM
teams
WHERE
(
sqlc.narg (hackathon_id)::uuid IS NULL
OR hackathon_id = sqlc.narg (hackathon_id)::uuid
)
ORDER BY
name;

-- name: InsertTeam :one
INSERT INTO
teams (name, slack_channel_id, tech_stack, phase, is_sos)
teams (
name,
slack_channel_id,
tech_stack,
phase,
is_sos,
hackathon_id,
slack_workspace_id
)
VALUES
($1, $2, $3, $4, $5)
($1, $2, $3, $4, $5, $6, $7)
RETURNING
*;

Expand Down
49 changes: 49 additions & 0 deletions apps/api/db/sqlcgen/hackathons.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 18 additions & 8 deletions apps/api/db/sqlcgen/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading