Skip to content

tsukuneA1/git_feed

Repository files navigation

ハッカソンW班 プロダクト

(あまりにも時間が足りず、完成させたいプロジェクトだったのですが全く終わりませんでした。反省作り直しているリポジトリ)

概要

GitFeedはソフトウェアエンジニアのための情報収集・交流サービスです。GitHubの静的な情報をTwitter ライクにユーザーが選択した形式で取得でき、かつTLでの発信も可能とし、エンジニアの情報収集の効率化および交流の活発化を目的とします

動機(発案者であるTsukuneA1の)

自分はエンジニアの情報を主にTwitterやQiitaやZennなど(たまにYouTube)で取得することが多いです。ただ最近はそこでストレスに感じることがあります。それは「AI系の発信が多すぎて疲れる」ということです。特にAI驚き屋みたいな非エンジニアのくせにこのAIがすごいとか言ってインプレッション稼ぎと情報商材を売っている輩は心底嫌いです。 自分はAIツールへのキャッチアップは生産性向上のためにもちろんすべきですが、本質はAIのモデルや性能ではなくその結果生み出される人間が介入したうえでの最終的な生成物の評価だと思っています。なので インプゾンビやポジショントークしかできないクズがいない クリーンな情報収集ツールを作ろうと考えました。エンジニアの一次情報は結局コードなのでGithubのAPIを叩き受動的に他人の活動を垂れ流し、Twitterライクではあるがクリーンなコードの情報を取得できる場を作りたいというのが第一の動機です。またエンジニアの主要な交流ツールがコードと直結しないTwitterであるということも疑問に思っています(ここはGithubでもConversationとかありますが、あれはクローズドでもう少し情報をオープンに取ってこれたらなという思想があります)。時間が余ればAIにリソースを与えてエンジニアの能力向上を促すような教師的な役割をさせたり出来たらなと思います。自分は思想が強いので少し大げさかもしれませんが、こういうことを考えているエンジニアは少なからずいるのではと思っています。

導線詳細

ER図(暫定)

erDiagram
  users {
    UUID id PK
    string username UK
    string display_name
    string avatar_url
    TIMESTAMP created_at
  }

  follows {
    %% CHECK: follower_id != followee_id
    UUID follower_id PK,FK
    UUID followee_id PK,FK
    TIMESTAMP created_at
  }

  posts {
    UUID id PK
    UUID user_id FK
    string content
    TIMESTAMP created_at
    TIMESTAMP updated_at
  }

  likes {
    UUID user_id PK,FK
    UUID post_id PK,FK
    TIMESTAMP created_at
  }

  github_subscriptions {
    UUID id PK
    UUID user_id FK
    %% XOR: (actor_remote_id IS NOT NULL) XOR (repo_remote_id IS NOT NULL)
     %% Github RESTのuser/org id(nullable)
    integer actor_remote_id
    %% Github RESTのrepo id(nullable)
    integer repo_remote_id  
    json filters
    TIMESTAMP created_at 
  }

  github_events {
    UUID id PK
    string remote_event_id
    string event_type
    TIMESTAMP event_time
    TIMESTAMP fetched_at
    integer actor_remote_id
    integer repo_remote_id
    string language_slug
    UUID language_id FK
    json payload
  }

  user_feed_seen {
    UUID user_id FK
    string remote_event_id
    TIMESTAMP seen_at
    %% PK(user_id, remote_event_id)
  }

  tags {
    UUID id PK
    string slug UK
    string label
    TIMESTAMP created_at
  }

  user_tag_prefs {
    UUID id PK
    UUID user_id FK
    UUID tag_id FK
    integer weight
    TIMESTAMP created_at
    TIMESTAMP updated_at
  }

  event_tags {
    UUID event_id FK
    UUID tag_id FK
    numeric share
    %% PK(event_id, tag_id)
  }

  users ||--o{ posts : "writes"
  users ||--o{ likes : "likes"
  posts ||--o{ likes : "is liked by"
  users ||--o{ follows : "follows"
  users ||--o{ follows : "is followed by"
  users ||--o{ github_subscriptions : "creates"
  users ||--o{ user_tag_prefs       : "has"
  tags  ||--o{ user_tag_prefs : "chosen"
  tags  ||--o{ event_tags     : "labels"
  github_events ||--o{ event_tags : "has"users ||--o{ posts : "writes"
  users ||--o{ likes : "likes"
  posts ||--o{ likes : "is liked by"
  users ||--o{ follows : "follows"
  users ||--o{ follows : "is followed by"
  users ||--o{ github_subscriptions : "creates"
  users ||--o{ user_tag_prefs       : "has"
  tags  ||--o{ user_tag_prefs : "chosen"
  tags  ||--o{ event_tags     : "labels"
  github_events ||--o{ event_tags : "has"
Loading

シーケンス図(暫定)

sequenceDiagram
  participant S as Scheduler(1–5min)
  participant Q as Queue(shards)
  participant J as Fetcher Job
  participant GH as GitHub API
  participant DB as DB

  S->>Q: enqueue targets (actor/repo)
  Q->>J: pop target
  J->>GH: GET events with ETag / If-Modified-Since
  alt 304 Not Modified
    GH-->>J: 304
    J->>DB: update last_polled_at / etag
  else New events
    GH-->>J: events[]
    J->>DB: UPSERT github_events by remote_event_id (unique)
    J->>DB: update cursor (last_seen_event_time, etag)
  end

Loading

ユーザーストーリー

EPIC := 大き目のテーマ、複数のユーザーストーリーを内包 US(User Story) := ユーザーストーリー、ユーザー視点の最小単位の要求 P0/P1/P2 := Priority 優先度

EPIC:認証
US-01(P0)

  • 「Sign in with Github」でサインイン
  • 初回サインインでなければ/feedへ
  • 初回サインインであれば初期設定ページへ

EPIC:初期設定
US-02(P0)

  • 「言語タグ」を3~5個選ぶ
  • その結果Feedに重みが反映
  • user_tag_prefsに保存

EPIC:Feedを見る(コード一次情報)
US-03(P0)

  • /feedを開く
  • 新しい順にGithubイベントカードが表示される
  • 3種(PR, Release, Issue)のカードが表示される
  • スクロールで10件ずつ(暫定)ずつ追加取得
  • 取得件数が0件の場合/discoverへの導線 US-04(P0)
  • Githubイベントカードから実際のgithub上のURLに遷移
  • 新規タブで開く US-05(P1)
  • PRのみ/merge済みのみ/言語などフィルタできる
  • 表示が即反映

EPIC:対象を見つけてサブスクリプション
US-06(P0)

  • /discoverrepo/actorを検索
  • サジェストから選択 US-07(P0)
  • filterをセットして「Save」
  • github_subscriptionにレコードが追加されFeedに反映

EPIC:自分の購読を管理
US-08(P0)

  • /subscriptionsで一覧が見える
  • 対象とfilters要約・未読件数が見える
  • 0件時は/discoverへ導線を設置
  • 削除/一時停止が可能

技術選定

フロントエンド

  • Next.js App Router: デファクトスタンダードでルーティングが直感的なので採用。(後から考えたらほぼCSRなのでReact Router v7+Viteとかでよかったです 2025/11/04)
  • TailwindCSS: CSSを分離する必要がないため即決
  • shadcn/ui: 他のUIライブラリ(MUI, chakra)は独自の思想があり、割とプレーンなものを使いたい。shadcnにチームの思想は宿らせることはできないが、プレーンなまま使う。v0とかとの互換性があるのも良き
  • Zustand: Reduxは学習コストが高くcontext apiはややパフォーマンスが悪い(なぜ採用したのか分からないです。TanStack Queryを使えばよかった 2025/11/04)

バックエンド

  • Ruby on Rails API Mode: 古い枯れた技術だが自分(TsukuneA1)が多少慣れている&wantedlyの求人数もそこそこある。学習の価値はあるので採用。あとgoとかで自分でアーキテクチャ組もうとしても恐らく破壊が起こるのでやれないしやりたくない。(破壊が起こる→理解不足で境界が曖昧なままになりそうだと考えていた。今思うとレイヤードでServiceを作るとかはやってもよかった 2025/11/04)
  • omniauth

競合および参考にしたいアプリ、サービス

  • daily.dev: 記事や動画などをスクローリングしてくる。完成度が高すぎて同路線で行くと勝負にならない
  • Github: そもそもサービスとしての提供したい機能・目的が違う

🚀 主要機能

予定機能(デモ版で実装済み)

  1. GitHub OAuth認証 - 安全なログイン・認証システム
  2. リポジトリデータ同期 - GitHub APIを通じた自動データ取得
  3. AIプロフィール解析 - OpenAI APIによるスキル・経験の自動分析
  4. コード品質解析 - リポジトリのコード品質評価とメトリクス算出
  5. エンジニアネットワーキング - スキル類似度によるエンジニア発見・マッチング
  6. AI チャット機能 - プロフィールに関するQ&A機能

🛠 技術スタック

技術的な詳細は docs ディレクトリを参照してください。

Core Technologies

  • Backend: Rails 8.0.2 (API mode) + PostgreSQL
  • Frontend: Next.js 15 (App Router) + TypeScript + Tailwind CSS
  • AI Integration: OpenAI GPT-3.5-turbo
  • Authentication: GitHub OAuth + JWT
  • External APIs: GitHub REST API, Octokit

⚡ クイックスタート

前提条件

  • Go Task: タスクランナー (インストールガイド)
  • pnpm: フロントエンドパッケージマネージャー
  • Ruby 3.3.7: バックエンド環境
  • Node.js 20+: フロントエンド環境
  • PostgreSQL: データベース

### 🚀 Task による一括開発環境セットアップ
```bash
# 依存関係のインストール
task install

# 開発サーバー起動(両方同時)
task dev

# 個別起動も可能
task backend:dev   # Rails (port 3000)
task frontend:dev  # Next.js (port 3001)

🔍 コード品質チェック

# 全体のコード品質チェック
task ci:all

# フロントエンド(Biome + ESLint + TypeScript)
task ci:frontend

# バックエンド(RuboCop)
task ci:backend

🧹 コードフォーマット

# 全体のフォーマット実行
task format

# 個別フォーマット
task frontend:format  # Biome + ESLint自動修正
task backend:format   # RuboCop自動修正

🪝 Pre-commit Hooks

# Git hooksを設定(初回のみ)
task hooks:install

# Pre-commit hookをテスト実行
task hooks:test

# コミット時に自動でCI相当のチェックが実行されます
git commit -m "feat: new feature"  # 自動でBiome/ESLint/TypeScript/RuboCopが実行

従来の手動起動方法

# Backend
cd backend
bundle install
rails db:create db:migrate
rails server -p 3000

# Frontend (別ターミナル)
cd frontend
pnpm install
pnpm dev  # port 3001で起動

アプリケーション:

🔄 CI/CD パイプライン

このプロジェクトではGitHub Actionsによる自動CI/CDが設定されています:

📋 ワークフロー詳細

# ローカルでのCI実行(GitHub Actions相当)
task ci:all  # 全ての品質チェックを実行

📚 ドキュメント

About

ハッカソンで使うリポジトリ

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 8