仕事でできることは仕事でやる できないことをここで供養しよう
This is a contents dump and search app made by s-hirano. Some codes are not best practices due to trying experimental features and new techs.
このプロジェクトでは、学習・検証を目的としてあえて幅広い技術スタックを採用しています。単一の最適解を追求するのではなく、様々な技術の実践的な知見を得ることを重視しています。
security labelpnpm audit (moderate+ severity threshold)savePrefix: '' in pnpm-workspace.yaml)allowBuilds + strictDepBuilds: true)blockExoticSubdeps: true)git clone https://github.com/s-hirano-ist/s-private.git
cd s-private
GitHubにブランチが作成されるとVercel cloudに自動的にPreview環境が構築される。
GitHubのmainブランチにPRがpullされるとProduction環境が更新される。
This project follows clean architecture principles with domain-driven design, ensuring separation of concerns and maintainable code structure.
├── packages/ # Monorepo packages
│ ├── core/ # Domain Layer (Core Business Logic)
│ │ ├── articles/ # News/link management domain
│ │ ├── notes/ # Markdown content domain
│ │ ├── images/ # File metadata domain
│ │ ├── books/ # ISBN-based book tracking domain
│ │ └── shared-kernel/ # Cross-domain shared logic
│ │
│ ├── database/ # Database Layer
│ │ └── prisma/ # Prisma ORM & migrations
│ │
│ ├── ui/ # Shared UI Components
│ │ ├── ui/ # shadcn/ui base components
│ │ ├── display/ # Display components (status, etc.)
│ │ ├── forms/ # Form components & fields
│ │ ├── layouts/ # Layout components (body, etc.)
│ │ ├── hooks/ # Shared React hooks
│ │ ├── providers/ # Context providers
│ │ └── utils/ # UI utilities
│ │
│ ├── notification/ # Notification services
│ │
│ ├── storage/ # MinIO Storage Client
│ │ └── src/ # MinIO client implementation
│ │
│ ├── search/ # RAG Search Library
│ │ └── src/ # Qdrant client, Embedding API client
│ │
│ └── scripts/ # Build & utility scripts
│ └── src/
│ ├── infrastructures/
│ └── rag/
│
└── app/src/ # Next.js Application
├── application-services/ # Application Layer (Use Cases)
│ ├── articles/
│ ├── notes/
│ ├── images/
│ ├── books/
│ ├── search/ # Search functionality
│ └── common/ # Shared application utilities
│
├── infrastructures/ # Infrastructure Layer (External Concerns)
│ ├── articles/ # Article repository implementation
│ ├── notes/ # Note repository implementation
│ ├── images/ # Image repository implementation
│ ├── books/ # Book repository implementation
│ ├── auth/ # Auth0 + NextAuth.js integration
│ ├── i18n/ # next-intl configuration
│ ├── observability/ # Sentry, logging, monitoring
│ ├── events/ # Event handling
│ ├── factories/ # Dependency injection factories
│ ├── search/ # Search infrastructure
│ └── shared/ # Shared infrastructure utilities
│
├── loaders/ # Data loading layer
│ ├── articles/
│ ├── notes/
│ ├── images/
│ └── books/
│
├── common/ # Shared utilities
│ ├── auth/
│ ├── error/
│ └── utils/
│
├── components/ # UI Components (Interface Layer)
│ ├── articles/
│ ├── notes/
│ ├── images/
│ ├── books/
│ └── common/
│
└── app/ # Next.js App Router
└── [locale]/ # Internationalized routes (en/ja)
├── (authenticated)/ # Authenticated (owner-only) pages
│ ├── articles/ # Articles management page (viewer/ = エクスポート済み閲覧ビュー)
│ ├── books/ # Books management page (viewer/, [slug]/)
│ ├── images/ # Images management page (viewer/)
│ ├── notes/ # Notes management page (viewer/, [slug]/)
│ └── error/ # Error page
├── book/[slug]/ # Book detail page
└── note/[slug]/ # Note detail page
Each domain is completely isolated with its own:
[locale] pattern for English/Japanese(authenticated) route group for owner-only content management pages┌──────────────┐ ┌─────────────────────────────────────────┐
│ Next.js App │ │ ConoHa VPS (Docker) │
│ (Vercel) │ │ │
│ │ CF │ ┌───────────────┐ │
│ packages/ │────▶│ │ HuggingFace │ Cloudflare Tunnel │
│ search/ │Tunnel│ │ TEI (:3001) │◀── cloudflared │
│ │ │ └───────────────┘ │
└──────┬───────┘ │ multilingual-e5-small │
│ └─────────────────────────────────────────┘
│
▼
┌──────────────┐
│ Qdrant │
│ (Vector DB) │
└──────────────┘
packages/search/ - RAG 検索ライブラリ(Qdrant クライアント、Embedding API クライアント、検索ロジック)compose.yaml で定義、ConoHa VPS にデプロイ)Content management system with clean domain separation:
UNEXPORTED → LAST_UPDATED → EXPORTED (all content types)userId for multi-tenant data separationSchema location: packages/database/prisma/schema.prisma
wrapServerSideErrorForClientrequireAuth() を呼ぶgit clone https://github.com/s-hirano-ist/s-private.git
cd s-private
mise install # Node.js, pnpm, Doppler CLI 等をインストール
pnpm install
環境変数は dev/preview 環境は Doppler、本番環境は Vercel Dashboard で管理します。
Vercel CLI に一本化しない理由:
vercel env runは dev 環境から本番環境の変数にもアクセスできてしまうため、セキュリティ上 dev/preview は Doppler で分離しています。
# .env.local にDopplerサービストークンを設定(Doppler Dashboard から発行)
echo "DOPPLER_TOKEN=dp.st.dev.xxxxxxxxxxxx" > .env.local
vercel link # 初回のみ: Vercel プロジェクトをリンク(prisma スクリプト用)
Mise が .env.local を自動読み込みし、doppler run が DOPPLER_TOKEN を検出して環境変数を取得します。doppler login / doppler setup は不要です。
pnpm dev / pnpm build / pnpm start 等の app スクリプトは doppler run 経由で環境変数を取得します。pnpm prisma:* 等のルートスクリプトは vercel env run -e development を使用します。
型定義とバリデーション: app/src/env.ts(@t3-oss/env-nextjs + Zod)
環境変数の全体的な管理戦略(ローカル・CI・本番・VPS)については環境変数管理を参照。
ローカル開発は CockroachDB Cloud の dev-db クラスタに直結します(ローカル DB は不要)。マイグレーション運用(migrate dev 不使用・DB 不要の diff フロー・schema_locked)の詳細は docs/setup.md を参照。
# (Optional) Open Prisma Studio for database inspection (クラウド dev-db に接続)
pnpm prisma:studio
# Start development server
pnpm dev
# Run development server with Next.js (http://localhost:3000)
# Hot reload enabled for all file changes
# Development
pnpm dev # Start Next.js development server
pnpm build # Build production application
pnpm start # Start production server
# Code Quality
pnpm format # Format + import/Tailwind class sorting (oxfmt)
pnpm format:check # Check formatting without writing (oxfmt)
pnpm lint # Lint (oxlint, type-aware)
pnpm lint:fix # Lint with auto-fixing (oxlint)
pnpm deps:check # Clean Architecture boundary check (dependency-cruiser)
# Testing
pnpm test # Run Vitest unit tests (storybook含む全プロジェクト)
pnpm typecheck # TypeScript type checking (全パッケージ)
# Component Development
pnpm storybook # Start Storybook (http://localhost:6006)
pnpm storybook:build # Build static Storybook
# Dead Code Detection
pnpm knip # Find unused files, dependencies, and exports
# Code Duplication Analysis
pnpm jscpd # Detect code duplication patterns
# Dependency Analysis
pnpm deps:check # Validate architectural boundaries and detect issues
pnpm deps:graph # Generate visual dependency graph (SVG)
pnpm deps:circular # Find circular dependencies
# Bundle Analysis
pnpm analyze # Analyze Next.js bundle size with webpack-bundle-analyzer
# Security & Licenses
pnpm security # Check for security vulnerabilities (moderate+)
pnpm security:fix # Auto-fix security vulnerabilities
pnpm security:report # Generate JSON security audit report
pnpm license:summary # Generate library license summary
pnpm license:check # Check for forbidden licenses (GPL, LGPL variants)
# Note: Automated security updates are handled by Renovate (weekly schedule)
# Renovate configuration: .github/renovate.json5
各ツールの設定詳細・CI連携については docs/code-analysis.md を参照。
# Prisma Commands (Prisma client は pnpm install 時に postinstall で自動生成)
pnpm --filter s-database prisma:migrate:diff # Generate migration SQL (DB 不要の diff フロー)
pnpm prisma:deploy # Deploy migrations (cloud dev-db / production)
pnpm prisma:studio # Open Prisma Studio database browser
# API Documentation (TypeDoc)
pnpm docs:build # Generate API docs (TypeDoc + DB schema)
pnpm docs:serve # Serve generated docs locally
pnpm docs:watch # Watch mode for TypeDoc
pnpm docs:clean # Remove generated documentation
# Output: docs/api/ (gitignored)
# Live: https://docs.s-hirano.com
typedoc.json uses packages strategy (packages/core, packages/ui, packages/notification)typedoc.json for granular controlprisma-dbml-generator auto-generates DBML from Prisma schema → dbml-renderer converts to SVGdocs:build generates all documentation at once (TypeDoc + DB schema HTML)*.test.ts, *.test.tsx@storybook/addon-a11ymain環境変数は dev/preview 環境は Doppler、本番環境は Vercel Dashboard で管理する。Vercel CLI に一本化しない理由は、vercel env run が dev 環境から本番環境の変数にもアクセスできてしまうため。
| 環境 | 管理方法 | 注入方法 |
|---|---|---|
| ローカル開発(app) | Doppler | doppler run -- <command>(app/package.json スクリプトに組み込み済み) |
| ローカル開発(prisma) | Vercel Dashboard (dev) | vercel env run -e development -- <command>(root package.json スクリプトに組み込み済み) |
| CI (GitHub Actions) | GitHub Secrets | ワークフローの env: で ${{ secrets.XXX }} として注入 |
| 本番 (Vercel) | Vercel Dashboard | ビルド・ランタイムに自動注入 |
| VPS (Docker Compose) | ~/s-private/.env |
Docker Compose が .env を自動読み込み |
mise install でツール一式をインストール(Node.js, pnpm, Doppler CLI 等).env.local に Doppler サービストークンを設定(Doppler Dashboard > dev 環境 > Access > Service Tokens から発行)vercel link で Vercel プロジェクトをリンク(初回のみ、prisma 用)pnpm dev / pnpm build / pnpm start 等の app スクリプトは Doppler から環境変数を取得pnpm prisma:* 等のルートスクリプトは Vercel dev 環境から環境変数を取得必要な GitHub Secrets:
DATABASE_URL, AUTH_SECRET, AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET, AUTH0_ISSUER_BASE_URL, SENTRY_AUTH_TOKEN, SENTRY_REPORT_URL, MINIO_HOST, MINIO_BUCKET_NAME, MINIO_ACCESS_KEY, MINIO_SECRET_KEY, PUSHOVER_USER_KEY, PUSHOVER_APP_TOKEN, QDRANT_URL, QDRANT_COLLECTION_NAME, NEXT_PUBLIC_SENTRY_DSNPRODUCTION_DATABASE_URL — Prisma マイグレーションデプロイ用NPM_TOKEN — パッケージ公開(release-please のみ)ACTIONS_GITHUB_TOKEN — リリース PR 作成環境変数が不要なジョブ(eslint, storybook)では SKIP_ENV_VALIDATION: "true" を設定。
VPS 上の Docker Compose サービス用の環境変数は ~/s-private/.env に配置する。詳細は docs/vps-deployment.md Step 7 を参照。
app/src/env.ts で @t3-oss/env-nextjs + Zod を使用し、ビルド時に全変数をバリデーションする。SKIP_ENV_VALIDATION を設定するとバリデーションをスキップできる。
../../* patternspackageManager field)Licensed under the AGPL-3.0 License, Copyright © 2024
See library-license.txt for the summary of licenses used in this project.
Automatic Updates: This file is automatically updated monthly via GitHub Actions.
To generate the license summary locally:
pnpm license:summary
See jscpd-summary.txt for the latest code duplication analysis on the main branch.
Automatic Updates: This file is automatically updated monthly via GitHub Actions.
To run code duplication analysis locally:
pnpm jscpd