# Sociofy プロダクト仕様書

最終更新: 2026-05-26

## 1. 目的

Sociofyは、1つのプロダクトに対して複数のソーシャルアカウントを運用し、SNS投稿の企画、静止画スライドショー生成、多言語化、承認、予約、投稿を自動化するプラットフォームである。

初期版は内部運用ツールとして構築する。ただし、設計上は将来的に外部顧客が自分のSNSアカウントを接続して利用するマルチテナントSaaSへ拡張できることを前提にする。

中核価値は以下である。

- 1つのプロダクトに対して、複数の編集切り口を持つ複数アカウントを運用する。
- 言語ごとに別アカウントを持ち、多言語展開を同時に進める。
- AIでスライドショー投稿を生成し、人間が承認してから公開する。
- TikTok、Instagram、YouTube Shorts向けの投稿物を同一ワークフローで扱う。

## 2. 確定済み決定事項

- 初期提供形態: 内部ツール。
- 将来提供形態: 外部公開可能なマルチテナントSaaS。
- 公開モデル: 投稿前に人間の承認を必須にする。
- コンテンツモデル: 静止画スライドショーを中心にする。AI生成モーション動画はMVP対象外。
- 動画出力: Instagram ReelsとYouTube Shorts向けに、静止画スライドから決定的にMP4を生成する。
- Instagram: CarouselとReelsの両方に対応する。ただし、投稿ごとに承認者が有効化する形式を選ぶ。
- YouTube: Shorts向けの縦型スライドショー動画を通常のYouTube動画アップロードAPIで投稿する。
- TikTok: MVPではPhoto Mode Direct Postのみを使う。
- SmartScout初期運用規模: 4編集切り口 x 4 active locale x 1日1投稿。
- 言語戦略: 言語ごとに別SNSアカウントを運用する。
- 対応言語: ユーザー選択式。MVPでは少なくとも英語、スペイン語、韓国語、中国語に対応する。
- 編集切り口: 人間が手動で定義する。Sociofyは切り口の作成、編集、有効化、言語別フィード化を扱い、AI/ChatGPTによる切り口提案機能はMVPに含めない。
- 公開メディアホスティング: AWS S3をオリジンストレージとし、CloudFront + カスタムドメインでSNS向け公開URLを提供する。
- 画像生成: OpenAI GPT Image 2、モデルID `gpt-image-2` を主画像生成モデルにする。
- 初期スライド構成: 1コンテンツパッケージは、AI生成画像4枚 + 固定CTA画像1枚の5枚構成にする。
- CTA画像: MVPでは固定アセットとして使い回す。将来的にCTAテンプレート、言語別CTA、商品別CTA、A/Bテストへ拡張できるようにする。
- AI/合成コンテンツ開示: 対応プラットフォームでは明示ラベルを有効化する。明示フィールドがない場合はキャプションで開示する。
- 本仕様書の主ファイル: `docs/specification.md`。

## 3. プロダクトコンセプト

### 3.1 アカウント戦略

1つのプロダクトに対して、複数の「切り口」または編集アカウントコンセプトを持つ。例:

- プロダクト教育アカウント
- ユースケース紹介アカウント
- データ/インサイト発信アカウント
- Founder/build-in-publicアカウント
- 特定ペルソナ向けニッチアカウント

初期設定時、オペレーターは人間が事前に考えた編集アカウントコンセプトをSociofyへ手動登録する。Sociofyは切り口の入力、編集、複製、有効化、言語別フィード作成を支援するが、切り口自体のAI提案やレコメンドは行わない。

各切り口は言語別にローカライズされ、言語ごとに別アカウントとして運用する。対応言語はプロダクトごとに設定可能だが、MVPでは最低限以下に対応する。

- 英語: `en`
- スペイン語: `es`
- 韓国語: `ko`
- 中国語: `zh-Hans` と `zh-Hant` を選択可能にする。SmartScout初期は繁体字 `zh-Hant` を中国語デフォルトにし、簡体字 `zh-Hans` は追加候補として残す。

論理フィードでは、`en-US`、`es-ES`、`es-419`、`ko-KR`、`zh-Hant` のようなロケール差分も扱えるようにする。

SmartScout初期運用では、既存4切り口 x 4 active locale = 16論理フィードを管理する。切り口数と言語数はプロダクトごとに変更可能にして、将来5切り口以上、または `zh-Hans` 追加へ拡張できるようにする。各論理フィードは以下のプラットフォーム接続先を持てる。

- TikTokアカウント
- Instagram professional account
- YouTubeチャンネル

### 3.2 コンテンツ戦略

Sociofyは、論理フィードごとに1日1つの承認済みコンテンツパッケージを生成する。

コンテンツパッケージは以下を含む。

- トピックと目的
- スライド構成
- ローカライズ済みスライドコピー
- 静止画スライド。MVPではAI生成画像4枚 + 固定CTA画像1枚。
- プラットフォーム別キャプションとハッシュタグ
- AI/合成コンテンツ開示フラグ
- プラットフォーム別レンディション
  - TikTok Photo Mode画像
  - Instagram Carousel画像
  - Instagram Reels MP4スライドショー
  - YouTube Shorts MP4スライドショー

## 4. MVPスコープ

### 4.1 MVP対象

- 内部管理者ログイン。
- プロダクトプロフィール管理。
- 手動入力された編集切り口と言語別アカウント管理。
- 手動または半自動のSNSアカウント接続。
- AIによるトピック、スライドコピー、キャプション、ローカライズ生成。
- 構造化スライドデータからの静止画スライド生成。
- 静止画スライドからの決定的MP4スライドショー生成。
- 人間の承認ワークフロー。
- 予約投稿。
- TikTok、Instagram、YouTube向けプラットフォームアダプター。
- 投稿ステータス追跡とリトライ。
- API制限の追跡とガードレール。
- ジョブ状態、失敗理由、再実行回数、生成コスト概算の記録。
- 生成、承認、投稿操作の監査ログ。
- API/workerの最低限のCloudWatch Logs。

### 4.2 MVP対象外

- レビューなしの完全自動投稿。
- AI生成モーション動画。
- 高度な分析最適化。
- コメント/返信自動化。
- 広告運用。
- 顧客課金。
- 外部顧客向けセルフサーブオンボーディング。
- シンプルな内部admin/editor/approver以上の細かいチーム権限管理。
- 本格的なモニタリング基盤。CloudWatch dashboard、CloudWatch alarms、X-Ray、OpenTelemetry、PagerDuty/オンコール連携、SLO/SLA管理はMVP対象外。
- AI/ChatGPTによる編集切り口の自動提案、レコメンド、ランキング。

### 4.3 推奨技術スタック

Sociofyは、内部MVPではTypeScript-firstの業務アプリケーションとして構築する。機能的に独立Repositoryへ切り分けるほどの境界はまだないため、初期は単一モノレポで進める。ドメイン設計はモジュラーモノリス寄りに保ちつつ、`apps/*` と `packages/*` で実行単位と共有コードを分離する。

社内でAWSを既に利用している前提のため、実行基盤、キュー、ストレージ、ログ、シークレット管理はAWS managed servicesを第一候補にする。例外は、AI生成のOpenAI、各SNSの公式API、既存開発ワークフローに密接なツールに限定する。

推奨スタック:

- リポジトリ: 単一モノレポ。`apps/web`、`apps/api`、`apps/worker`、`packages/shared`、`packages/ui`、`packages/config`を基本構成にする。
- パッケージマネージャ: `pnpm` workspace。
- Build orchestration: Turborepo。`build`、`lint`、`test`、`typecheck`、`db:migrate`、`deploy`の依存関係とキャッシュを管理する。
- フロントエンド: React SPA、TypeScript、MUI v7、Emotion。SSRはMVPでは採用しない。
- フロントエンドホスティング: AWS S3 + CloudFront。S3 bucketはprivateにし、CloudFront Origin Access Controlを使って直接S3アクセスを防ぐ。
- バックエンドAPI: 既存バックエンド標準に合わせたTypeScript API。NestJSを使う場合も、workspace分割、lint/test/release手順はモノレポのTurborepo pipelineに合わせる。REST/JSONとOpenAPI schema generationを提供する。
- API実行基盤: Amazon ECS on AWS Fargate、Amazon ECR、Application Load Balancer。外部SaaS化時にAPI Gateway + WAFを追加検討する。
- データベース: Amazon Aurora PostgreSQL Serverless v2を第一候補にする。既存DB運用や固定負荷/コスト予測性を優先する場合は、現行と同じ非ServerlessのRDS/Aurora PostgreSQL構成を選択できる。
- ORM/migration: TypeORM。バックエンド側のリリース手順、migration実行、rollback手順と統一するためPrismaは採用しない。
- キュー/ジョブ: Amazon SQS standard queues + dead-letter queues。厳密な順序制御が必要なジョブだけFIFO queueを使う。
- スケジューリング: Amazon EventBridge Schedulerで投稿予定時刻にpublish jobを投入する。
- オーケストレーション: AWS Step FunctionsはMVP標準にしない。`ContentPackage`、`PlatformRendition`、`PublishJob`、`JobAttempt`のDB状態を正とし、SQS workerが次のjobを作る薄い自前オーケストレーターを実装する。デバッグ、再実行、監査、手動リカバリをアプリケーション上で追えることを優先する。
- オブジェクトストレージ: AWS S3 private origin buckets。
- 公開メディア配信: CloudFront + カスタム検証済みメディアドメイン。
- レンダリング: ECS Fargate worker、Node、SVG/テンプレート合成、Sharp、FFmpeg。
- キャッシュ/レート制御: Amazon ElastiCache for Valkeyは任意。MVPではSQSをジョブキューにし、ElastiCacheは高頻度参照キャッシュや分散rate-limitが必要になった時だけ導入する。
- AIプロバイダー: OpenAI Responses APIで企画/コピー/ローカライズ、OpenAI Image API `gpt-image-2` でビジュアル生成。
- アプリ認証: Amazon Cognito User Poolsを第一候補にする。社内利用では既存IdPやIAM Identity CenterとのSAML/OIDC連携を使い、外部SaaS化時もtenant/user管理へ拡張する。SNSプラットフォームOAuth tokenはCognitoとは分けて管理する。
- シークレット管理: AWS Secrets Manager + AWS KMS。SNS access token、refresh token、OpenAI API key、DB credentialを集中管理する。
- ログ/運用可視性: MVPではAmazon CloudWatch Logs、DB上のジョブ状態、JobAttempt、監査ログ、生成コスト概算を必須にする。CloudWatch Metrics/Alarms、dashboards、AWS X-Ray、AWS Distro for OpenTelemetry、外部通知連携はMVP後の運用強化で導入する。
- インフラ: AWS CDK TypeScript。S3、CloudFront、ACM、WAF、Aurora/RDS、ECS/Fargate、ECR、SQS、EventBridge Scheduler、Cognito、Secrets Manager、KMS、CloudWatch LogsをMVP範囲で管理する。CloudWatch Metrics/AlarmsやdashboardはMVP後に追加する。
- CI/CD: モノレポのTurborepo pipelineを前提にする。変更差分に応じて対象workspaceのbuild/test/deployだけを実行し、フロントエンドはS3 deploy + CloudFront invalidation、バックエンド/ワーカーはcontainer build + ECS deployを標準にする。CodePipeline/CodeBuildまたは既存CIのどちらを使うかは社内標準に合わせる。
- テスト: VitestまたはJest、Playwright、Testcontainers、必要に応じてLocalStack。

技術スタック対応表:

| 領域 | 標準案 |
| --- | --- |
| Repository | 単一モノレポ、`apps/*` + `packages/*` |
| Package manager | pnpm workspace |
| Build orchestration | Turborepo |
| Web frontend | React SPA、TypeScript、MUI v7、Emotion |
| Web hosting | S3 private bucket + CloudFront + OAC |
| API/worker runtime | ECS Fargate、ECR、ALB |
| Database | Aurora PostgreSQL Serverless v2、または既存方針に合わせたRDS/Aurora PostgreSQL |
| ORM/migration | TypeORM |
| Queue | SQS standard/FIFO、dead-letter queue |
| Schedule | EventBridge Scheduler |
| Orchestration | DB-backed thin orchestrator、SQS workers、Step FunctionsはMVP対象外 |
| Media storage | S3 private buckets |
| Public media delivery | CloudFront、ACM、WAF |
| User auth | Cognito User Pools、必要に応じてIAM Identity Center/既存IdP |
| Secrets | Secrets Manager、KMS |
| Operational visibility | MVP: CloudWatch Logs、DB job status、JobAttempt、audit log、cost tracking。MVP後: CloudWatch Metrics/Alarms、dashboard、X-Ray/OpenTelemetry |
| Infrastructure | AWS CDK TypeScript、既存CIまたはCodePipeline/CodeBuild |

## 5. ユーザーとロール

### 5.1 Internal Admin

プロダクト、アカウント、プラットフォーム認証情報、グローバル設定、API制限を設定できる。

### 5.2 Editor

コンテンツの生成、編集、ローカライズ、プレビュー、レビュー依頼ができる。

### 5.3 Approver

承認、修正依頼、予約、キャンセル、手動投稿実行ができる。

### 5.4 System Worker

生成、レンダリング、投稿、ステータス取得、トークン更新、クリーンアップをバックグラウンドで実行する。

## 6. コアワークフロー

```mermaid
flowchart TD
  A[Product profile] --> B[Content planning]
  B --> C[AI draft generation]
  C --> D[Slide and caption localization]
  D --> E[Static asset rendering]
  E --> F[Platform rendition rendering]
  F --> G[Human review]
  G -->|Approve| H[Schedule]
  G -->|Request changes| C
  H --> I[Publish jobs]
  I --> J[Status polling]
  J --> K[Published / Failed]
```

### 6.1 プロダクト設定

必須フィールド:

- プロダクト名
- プロダクトURL
- プロダクトカテゴリ
- 短い説明
- 主な価値提案
- 機能一覧
- ターゲットユーザー
- 証明可能な主張と許可された訴求
- 禁止主張
- 競合とポジショニング
- ブランドトーン
- ビジュアルスタイルガイド
- CTAライブラリ
- 対応言語とロケール

対応言語ルール:

- プロダクトオーナーはプロダクトごとに対応言語を選択できる。
- MVPの基準対応言語は英語、スペイン語、韓国語、中国語。
- 中国語はProductごとにデフォルトscriptを選ぶ。SmartScout初期は繁体字 `zh-Hant` をデフォルトにし、簡体字 `zh-Hans` はcandidate localeとして残す。
- `es-ES` と `es-419`、`en-US` と `en-GB`、`zh-Hans` と `zh-Hant` を区別できるよう、languageとlocaleを分けて保存する。
- 言語数は固定上限にしない。AI翻訳/ローカライズ自体は増やしやすいが、active化はアカウント作成、承認、投稿先準備、品質確認、運用分析の準備状態で管理する。

### 6.2 編集切り口設定

Sociofyは、編集切り口の自動提案機能をMVPに含めない。初期の切り口は人間が手動で考え、オペレーターが管理画面から登録する。SmartScout初期は既存運用にある4つの切り口を取り込む。

切り口設定ルール:

- オペレーターはプロダクトごとに任意数のアクティブ切り口を手動登録する。SmartScout初期は4つを登録する。
- Sociofyは `EditorialAngle` のCRUD、複製、並び替え、有効/無効切り替えを提供する。
- CSVまたは簡易フォームでの一括登録を許容する。
- 各切り口は、作成後に言語別 `LogicalFeed` へ展開される。
- 切り口の良し悪しの評価、候補生成、ランキングはMVP対象外にする。

切り口必須フィールド:

- 切り口名
- オーディエンス/ペルソナ
- コンテンツミッション
- トピック柱
- トーン修飾子
- CTA戦略
- 投稿頻度
- プラットフォーム投稿先
- 言語別アカウントマッピング

### 6.3 コンテンツ生成

生成結果は単なる文章ではなく、構造化出力にする。

必須構造:

```json
{
  "topic": "string",
  "objective": "awareness | education | activation | retention",
  "angle_id": "string",
  "language": "string",
  "slides": [
    {
      "index": 1,
      "role": "hook | body | proof | cta",
      "headline": "string",
      "body": "string",
      "visual_prompt": "string",
      "alt_text": "string"
    }
  ],
  "captions": {
    "instagram": "string",
    "tiktok_title": "string",
    "tiktok_description": "string",
    "youtube_title": "string",
    "youtube_description": "string"
  },
  "hashtags": ["string"],
  "disclosures": {
    "synthetic_media": true,
    "own_brand_promotion": true,
    "paid_partnership": false
  }
}
```

### 6.4 人間レビュー

レビューUIでは以下を表示する。

- プロダクトと切り口コンテキスト。
- 言語と対象アカウント。
- 全スライドの順序付きプレビュー。
- プラットフォーム別プレビュー。
- プラットフォーム別キャプション。
- 開示ラベルとブランドラベル。
- 予約時刻。
- API準備警告。
- 投稿上限警告。

承認はコンテンツパッケージ単位で必須にする。プラットフォーム別レンディションは、予約前に個別に無効化できる。

Instagram固有レビュー規則:

- 承認者はコンテンツパッケージごとにCarousel、Reels、または両方を選ぶ。
- デフォルト推奨は1コンテンツパッケージにつきInstagram 1形式。
- 両方の有効化は許可するが、毎日のデフォルト運用にはしない。

### 6.5 スケジューリング

スケジューリングルール:

- デフォルトは論理フィードごとに1日1つの承認済みコンテンツパッケージ。
- SmartScout初期合計は16コンテンツパッケージ/日。
- Instagramのデフォルト動作は、1コンテンツパッケージにつき1つのInstagram出力を選ぶこと。
- 想定されるデフォルト投稿ジョブ/日:
  - TikTok Photo: 16
  - Instagram selected output、CarouselまたはReels: 16
  - YouTube Shorts: 16
  - 合計: 48 platform publish jobs/day
- 全コンテンツパッケージでInstagramの両形式を有効化した場合の上限:
  - 64 platform publish jobs/day
- Schedulerは、設定済みのアカウント/プラットフォーム制限を超える投稿を防ぐ。
- Schedulerはアカウントごとのtimezoneをサポートする。

## 7. コンテンツレンダリング要件

### 7.1 マスタースライドアセット

スライドアセットはまず画像として生成する。画像生成後も、テキストは構造化コンテンツレベルで編集可能に保持する。

必要な画像レンディション:

- `vertical_9_16`: 1080x1920。Reels、Shorts、TikTok Photo/video fallback向け。
- `portrait_4_5`: 1080x1350。Instagram Carousel向け。
- `square_1_1`: 1080x1080。Instagram Carousel fallbackおよびクロスプラットフォーム互換向け。

### 7.2 スライドショー動画レンダリング

動画レンダリングは、静止画スライドからMP4への決定的変換とする。

- フォーマット: MP4。
- コーデック: H.264。
- 解像度: 1080x1920。
- フレームレート: 30 FPS。
- スライド表示時間デフォルト: 2.5-3.0秒。
- 合計尺デフォルト: 15-45秒。
- トランジション: simple cutまたはcrossfadeのみ。
- 音声: デフォルトではsilent AAC track。将来版でライセンス済み音楽に対応してもよい。
- ウォーターマーク: デフォルト無効。TikTok API共有コンテンツでは不要なプロモーションウォーターマークを避ける。

### 7.3 スライド枚数デフォルト

- MVPの標準構成は5枚。
  - 1-4枚目: GPT Image 2で生成する本文スライド。
  - 5枚目: 固定CTA画像。
- 固定CTA画像は日次生成しない。プロダクト、言語、CTA文言、ブランドデザインを変更した場合のみ再生成または再レンダリングする。
- Instagram Carousel: MVPでは5枚を標準とし、将来の可変構成では最大10枚までサポートする。
- TikTok Photo Mode: TikTok API上限は35 image URLsだが、Sociofyでは5枚を標準とし、将来の可変構成でも10-12枚を上限目安にする。
- Reels/Shorts video: MVPでは5枚構成を標準にする。将来は5-12枚をサポートする。

将来変更に備え、スライド構成はコードにハードコードしない。プロダクトまたはテンプレート設定として以下を持つ。

- `generated_slide_count`: 初期値4。
- `cta_slide_count`: 初期値1。
- `cta_asset_id`: 固定CTA画像の参照。
- `cta_position`: 初期値 `last`。
- `allow_variable_slide_count`: 初期値 `false`。

### 7.4 AI画像生成

生成スライドビジュアルは、OpenAI GPT Image 2、モデルID `gpt-image-2` を主モデルにする。

生成要件:

- 一枚絵の生成にはOpenAI Image APIを使う。
- MVPでは、1コンテンツパッケージあたり4枚だけをGPT Image 2で生成する。
- 固定CTA画像は日次生成対象から除外し、承認済みアセットを再利用する。
- model ID、prompt、prompt version、requested size、quality、output format、moderation result、token/cost metadataを保存する。
- 生成されたオリジナルを、派生変換前にS3へ永続化する。
- プラットフォーム別レンディションは、オリジナル画像の保存後に生成または変換する。
- 最終承認済みスライドコピーは、構造化データとして編集可能に保持する。
- コンプライアンス上重要なテキストや厳密なローカライズ文字列については、モデル生成画像内の文字だけに依存せず、スライドレンダラーで決定的にテキスト合成する。
- モデル生成画像内にテキストを含める場合は、人間レビューUIで最終プラットフォームサイズの表示を確認できるようにする。
- OpenAI organization verificationや画像moderation failureをreadiness checkに含める。

## 8. プラットフォームAPI仕様

プラットフォームAPIの挙動は頻繁に変わる。実装前、本番ローンチ前、外部SaaS公開前には公式ドキュメントを再確認する。

### 8.1 共通API設計

全プラットフォーム連携は、共通インターフェースの裏にアダプターとして実装する。

```ts
interface SocialPublisher {
  validate(job: PublishJob): Promise<ValidationResult>;
  publish(job: PublishJob): Promise<PublishInitResult>;
  pollStatus(job: PublishJob): Promise<PublishStatus>;
  cancel?(job: PublishJob): Promise<void>;
}
```

アダプター要件:

- UIから直接呼び出さない。
- 必ずキュー化されたジョブから実行する。
- idempotency keyを使う。
- raw request IDとplatform response IDを保存する。
- platform error code、HTTP status、response body summaryを保存する。
- アカウント別/アプリ別rate limitを適用する。
- tokenとsigned media URLをログでredactする。

### 8.2 公開アセットホスティング

TikTokとInstagramは、主要フローでプラットフォーム側がURLからメディアを取得する。Sociofyは、投稿時に生成画像/動画を公開HTTPS URLでホストする必要がある。

ストレージ決定:

- 生成オリジナルと非公開派生物はAWS S3に保存する。
- 投稿URLはCloudFrontのSociofy管理カスタムメディアドメインで配信する。
- 直接S3 public URLは、ローカル開発または内部テストアカウントに限定する。
- 本番のプラットフォーム取得URLでは、query token付きsigned URLではなく、publish-specific prefix配下のランダムで非機密なobject keyを使う。
- S3 lifecycle ruleで、一時公開オブジェクトを保持期間後に削除する。

アセットURL要件:

- HTTPSのみ。
- TikTok Pull From URLではリダイレクトなし。
- TikTok向けに所有確認済みdomainまたはURL prefixを使う。本番ではraw S3 domainではなくCloudFront custom media domainを使う。
- Meta/TikTok fetcherから投稿中に公開アクセス可能である。
- 有効期限はプラットフォーム取得/投稿ウィンドウより後にする。
- 推奨最小有効期限: scheduled publishから48時間後。
- アセットURLにinternal ID、token、customer secretsを含めない。

### 8.3 TikTok

MVPではTikTok Photo Mode direct postのみを使う。TikTok video slideshow fallbackは、この決定を明示的に見直すまでMVPでは使わない。

必要な製品/スコープ:

- TikTok Developer app。
- Content Posting API product。
- Direct Post用の `video.publish`。
- upload/draft flowsを使う場合のみ `video.upload`。

関連エンドポイント:

- `POST /v2/post/publish/creator_info/query/`
- `POST /v2/post/publish/content/init/` for photos
- `POST /v2/post/publish/video/init/` for future video fallback
- `POST /v2/post/publish/status/fetch/`
- `POST /v2/post/publish/cancel/` for cancellable Pull From URL tasks
- `POST /v2/oauth/token/` for token exchange and refresh

Photo post制約:

- `media_type`: `PHOTO`
- `post_mode`: `DIRECT_POST`
- Source: `PULL_FROM_URL` only
- `photo_images`: 最大35個の公開アクセス可能なapp-verified image URLs
- `photo_cover_index`: zero-based cover index
- 対応画像形式: WebP、JPEG
- 画像サイズ: 最大20 MB/枚
- Title max: 90 UTF-16 runes
- Description max: 4000 UTF-16 runes
- Rate limit: `content/init` endpointはuser access tokenごとに6 requests/minute

将来のvideo fallback制約:

- Direct Post endpoint: `/v2/post/publish/video/init/`
- Source: `FILE_UPLOAD` または `PULL_FROM_URL`
- 対応フォーマット: MP4、WebM、MOV
- 対応コーデック: H.264、H.265、VP8、VP9
- Frame rate: 23-60 FPS
- Size: 最大4 GB
- Duration: creator-dependent。投稿前に `creator_info/query` で `max_video_post_duration_sec` を取得する。

TikTok認証と監査:

- Access tokenは24時間で期限切れ。
- Refresh tokenは365日で期限切れ。
- `expires_at` と `refresh_expires_at` を保存し、サーバー側でrefreshする。
- Direct Postにはuser authorizationが必要。
- 未監査clientには制限がある。公開production postingにはTikTok audit approvalが必要。

TikTok開示:

- 自社プロダクトのプロモーションでは、必要に応じて `brand_organic_toggle=true` を設定する。
- Paid partnershipでは `brand_content_toggle=true` を設定する。
- Video fallbackでは該当時に `is_aigc=true` を設定する。
- Photo Modeで明示的なAIGC fieldがない場合は、現行ポリシーに従ってdescription内に開示文を入れる。

### 8.4 Instagram

Instagramでは、Instagram professional accountとMeta platform setupが必要である。

MVP対象フォーマット:

- 静止画スライド画像からのInstagram Carousel。
- 決定的スライドショーMP4からのInstagram Reels。

運用決定:

- SociofyはCarouselとReelsの両方のレンディションをサポートする。
- 承認者はコンテンツパッケージごとにInstagram形式を選ぶ。
- デフォルト推奨は1コンテンツパッケージにつき1つのInstagramレンディション。
- コンテンツがInstagram内の重複配信に明確に向いている場合のみ、両方を手動で有効化できる。

Facebook Login pathで必要な権限:

- `instagram_basic`
- `instagram_content_publish`
- `pages_read_engagement`
- app user roleがBusiness Manager経由で付与される場合、Metaが `ads_management` または `ads_read` を追加要求することがある。

関連エンドポイント:

- `POST /{ig-user-id}/media` to create media containers
- `POST /{ig-user-id}/media_publish` to publish containers
- `GET /{ig-container-id}?fields=status_code` to poll container status
- `GET /{ig-user-id}/content_publishing_limit` to check publishing limit usage
- `POST https://rupload.facebook.com/ig-api-upload/{version}/{ig-container-id}` for resumable video upload

共通制約:

- URL-based publishingで使うmediaはpublic server上にある必要がある。
- Containerは24時間で期限切れ。
- Instagram accountはrolling 24-hour period内に400 containersを作成可能。
- 接続PageにPage Publishing Authorizationやtwo-factor authenticationが必要な場合、完了まで投稿が失敗する可能性がある。
- Caption max: 2200 characters、30 hashtags、20 @ tags。
- Shopping tagsとfiltersはContent Publishingでは非対応。

Rate limit note:

- Meta documentationには現在published-post limitの記載差がある。
  - Content Publishing guide: 24-hour moving periodあたり100 API-published posts。
  - `media_publish` reference: 24-hour moving periodあたり50 posts。
- Sociofyでは安全側の50 posts/account/24hを強制し、投稿前に `content_publishing_limit` を呼ぶ。

Instagram Carousel制約:

- Child media containersを先に作成する。
- Parent containerは `media_type=CAROUSEL` と `children` を使う。
- Reelsはcarousel childrenとして使えない。
- Sociofy MVPではcarousel slidesを10 itemsに制限する。
- Carousel imagesはJPEG、最大8 MB、sRGB。
- Feed image containersではaspect ratioが4:5から1.91:1の範囲に収まる必要がある。
- SociofyはCarousel向けに `portrait_4_5` または `square_1_1` レンディションを使う。

Instagram Reels制約:

- `media_type=REELS`
- Standard uploadでは `video_url` を使える。
- Resumable uploadでは `upload_type=resumable` を使える。
- Sociofy推奨出力: 1080x1920 MP4、H.264、30 FPS。
- Meta specs上はMOV/MP4、H.264/HEVC、23-60 FPSが許容される。
- Reels duration: 3秒以上、15分以下。
- Reels file size: 最大300 MB。
- 必要に応じて生成JPEG coverを `cover_url` で指定する。

Instagram開示:

- コンテンツが生成物である場合、captionにAI/合成コンテンツ開示を追加する。
- Product promotion rulesでbranded content labelsが必要な場合、後続フェーズでpartner taggingとbranded content configurationをサポートする。

### 8.5 YouTube Shorts

YouTube Shortsは通常のYouTube Data API video upload endpointでアップロードする。Shorts専用の公開endpointはない。

必要OAuth scope:

- `https://www.googleapis.com/auth/youtube.upload`

関連エンドポイント:

- `POST https://www.googleapis.com/upload/youtube/v3/videos`
- API method: `videos.insert`

Shorts制約:

- Short-form verticalまたはsquare videoをアップロードする。
- Shorts fileは3分以内。
- Sociofyは1080x1920 MP4 slideshow videoを生成する。
- 運用慣習としてdescriptionに `#Shorts` を含める。ただし、現行のYouTube分類は主に長さとaspect ratioに依存する。

YouTube Data API制約:

- `videos.insert` upload cost: 100 quota units。
- Default project quota: 10,000 units/day。
- SmartScout初期計画の16 YouTube uploads/dayは、追加reads/polls前で約1,600 units/day。
- `videos.insert` の最大file sizeは256 GBだが、Sociofy videosはそれより十分小さく保つ。
- 2020-07-28以降に作成された未検証API projectsは、アップロード動画がprivateになる。公開production postingにはYouTube API Services auditが必要。

YouTube metadata:

- `snippet.title`、`snippet.description`、`snippet.tags`、`snippet.defaultLanguage`、`status.privacyStatus` を設定する。
- `status.selfDeclaredMadeForKids` を明示的に設定する。
- AI生成または現実的な合成コンテンツの場合は `status.containsSyntheticMedia=true` を設定する。
- `status.publishAt` は、互換性のあるprivacy settingsと現行API挙動を確認したうえで使う。

## 9. データモデル

### 9.1 中核エンティティ

```mermaid
erDiagram
  PRODUCT ||--o{ EDITORIAL_ANGLE : has
  PRODUCT ||--o{ ANGLE_RECOMMENDATION : receives
  PRODUCT ||--o{ PRODUCT_KNOWLEDGE_ITEM : has
  EDITORIAL_ANGLE ||--o{ LOGICAL_FEED : localized_as
  LOGICAL_FEED ||--o{ SOCIAL_ACCOUNT : publishes_to
  LOGICAL_FEED ||--o{ CONTENT_PACKAGE : receives
  CONTENT_PACKAGE ||--o{ SLIDE : contains
  CONTENT_PACKAGE ||--o{ PLATFORM_RENDITION : renders
  PLATFORM_RENDITION ||--o{ PUBLISH_JOB : publishes
  SOCIAL_ACCOUNT ||--o{ SOCIAL_CREDENTIAL : authenticates
```

### 9.2 Product

フィールド:

- `id`
- `name`
- `url`
- `category`
- `description`
- `brand_voice`
- `visual_style`
- `allowed_claims`
- `disallowed_claims`
- `default_ctas`
- `supported_languages`
- `created_at`
- `updated_at`

### 9.3 EditorialAngle

フィールド:

- `id`
- `product_id`
- `name`
- `audience`
- `mission`
- `topic_pillars`
- `tone_modifiers`
- `posting_cadence`
- `active`

### 9.4 LogicalFeed

1つの切り口と言語の組み合わせである投稿フィードを表す。

フィールド:

- `id`
- `product_id`
- `editorial_angle_id`
- `language`
- `locale`
- `timezone`
- `daily_post_target`
- `active`

### 9.5 SocialAccount

フィールド:

- `id`
- `logical_feed_id`
- `platform`: `tiktok | instagram | youtube`
- `display_name`
- `platform_account_id`
- `handle`
- `status`: `connected | needs_reauth | disabled | failed`
- `capabilities`
- `rate_limit_config`
- `last_verified_at`

### 9.6 ContentPackage

フィールド:

- `id`
- `logical_feed_id`
- `topic`
- `objective`
- `language`
- `source_prompt_version`
- `status`
- `scheduled_at`
- `approved_by`
- `approved_at`
- `created_at`
- `updated_at`

ステータス値:

- `draft`
- `generated`
- `needs_review`
- `changes_requested`
- `approved`
- `scheduled`
- `rendering`
- `ready_to_publish`
- `publishing`
- `published`
- `partially_published`
- `failed`
- `cancelled`

### 9.7 Slide

フィールド:

- `id`
- `content_package_id`
- `index`
- `role`
- `headline`
- `body`
- `visual_prompt`
- `alt_text`
- `assets`

### 9.8 PlatformRendition

フィールド:

- `id`
- `content_package_id`
- `platform`
- `format`: `photo | carousel | reels | shorts | video_fallback`
- `asset_ids`
- `caption`
- `hashtags`
- `disclosure_config`
- `validation_status`
- `render_status`
- `enabled`

### 9.9 PublishJob

フィールド:

- `id`
- `platform_rendition_id`
- `social_account_id`
- `scheduled_at`
- `status`
- `idempotency_key`
- `platform_publish_id`
- `platform_media_id`
- `platform_status`
- `attempt_count`
- `last_error_code`
- `last_error_message`
- `started_at`
- `completed_at`

ステータス値:

- `queued`
- `validating`
- `rendering`
- `uploading`
- `publishing`
- `polling`
- `published`
- `failed_retryable`
- `failed_final`
- `cancelled`

## 10. 内部API要件

内部バックエンドは以下のAPIエンドポイントを提供する。

- Products CRUD。
- Editorial angles CRUD。
- Editorial anglesの一括登録、複製、有効/無効切り替え。
- Logical feeds CRUD。
- Social accounts CRUDと接続状態確認。
- Content package生成。
- Content package編集。
- Slide並び替え、編集、再生成。
- Rendition preview。
- 承認操作。
- 予約操作。
- Publish job status確認。
- 手動リトライ。
- Audit log read。

Endpoint例:

```http
POST /api/products/{id}/editorial-angles
PATCH /api/editorial-angles/{id}
POST /api/editorial-angles/{id}/duplicate
POST /api/content-packages/{id}/submit-for-review
POST /api/content-packages/{id}/approve
POST /api/content-packages/{id}/request-changes
POST /api/content-packages/{id}/schedule
POST /api/publish-jobs/{id}/retry
GET  /api/social-accounts/{id}/readiness
```

## 11. バックグラウンドジョブ

必要なワーカー:

- `GenerateTopicJob`
- `GenerateContentPackageJob`
- `LocalizeContentJob`
- `RenderSlideImagesJob`
- `RenderSlideshowVideoJob`
- `ValidatePlatformRenditionJob`
- `PublishJob`
- `PollPublishStatusJob`
- `RefreshTokenJob`
- `SyncRateLimitJob`
- `PruneExpiredAssetsJob`
- `NotifyFailureJob`

ジョブは冪等でなければならない。投稿ジョブは、ワーカー停止後に重複投稿を避けられるだけのplatform stateを保存する。

## 12. 準備チェック

コンテンツパッケージを予約可能にする前に、Sociofyは以下を検証する。

- 必要なスライドアセットがすべて存在する。
- プラットフォーム別レンディションが生成済み。
- キャプションがプラットフォーム制限内に収まる。
- 必要な開示フィールドが設定済み。
- OpenAI画像生成がproduct workspaceで利用可能。
- GPT Image 2に必要な場合、OpenAI organization verificationが完了済み。
- Social accountが接続済み。
- Tokenが予約投稿ウィンドウまで有効。
- 公開アセットURLが利用可能。
- TikTok URL/domainが検証済み。
- Instagram accountがprofessionalかつeligible。
- YouTube quota estimateが取得可能。
- プラットフォーム投稿上限を超えない。

## 13. エラーハンドリング

### 13.1 リトライ可能エラー

- ネットワークタイムアウト。
- 5xxプラットフォームエラー。
- アップロードチャンクの一時的失敗。
- ステータス取得がpending。
- `retry-after` がある一時的rate limit。

### 13.2 最終エラー

- トークンが無効でrefreshにも失敗した。
- 必須permission/scopeが不足している。
- TikTok URL ownershipが未検証。
- Instagram containerが期限切れ。
- メディア形式が不正。
- OpenAI画像生成のmoderationまたはpolicy failure。
- YouTube quotaが当日分を超過。
- プラットフォームアカウントが投稿禁止または停止状態。
- プラットフォーム監査制限により公開投稿できない。

### 13.3 リトライ方針

- jitter付きexponential backoffを使う。
- 最終エラーは自動リトライしない。
- Platform publish IDがすでに存在する場合、adapterが前回試行の公開前失敗を確認しない限り、新しいplatform postを作らない。

## 14. セキュリティ要件

内部MVP:

- 管理者認証を必須にする。
- プラットフォームトークンは保存時に暗号化する。
- Secretsをログに残さない。
- Signed/internal asset URLsから永続アクセス権が漏れないようにする。
- S3 bucketsは、public media domain経由の明示的publish prefixを除きprivateに保つ。
- 投稿操作は監査ログに記録する。
- 承認者IDを記録する。

外部SaaS化に向けて:

- テナント分離。
- テナントごとの暗号化境界またはkey scoping。
- セルフサーブOAuth接続/解除。
- 権限スコープ付きユーザーロール。
- データexport/delete workflows。
- Abuse preventionとcontent policy enforcement。
- Platform app review evidenceとscreencasts。

## 15. コンプライアンスと開示

Sociofyは透明なラベリングをデフォルトにする。

開示ルール:

- Generated slideshow contentはinternal metadata上AI-assistedとして扱う。
- TikTok video fallbackでは該当時に `is_aigc=true` を設定する。
- YouTubeでは該当時に `status.containsSyntheticMedia=true` を設定する。
- TikTok上のproduct promotionでは、実際の関係に応じてbrand organic/paid togglesを設定する。
- Platform-specific metadataに明示フィールドがない場合、captionに設定可能なdisclosure phraseを含める。

プロダクトプロフィールには、規制リスクや広告ポリシーリスクを下げるため、禁止主張を定義する。

## 16. 容量計画

初期対象:

- SmartScout初期は4 editorial angles。
- 4 active localeをoperatorが選択。MVP baseline supportは英語、スペイン語、韓国語、中国語。
- 16 logical feeds。
- 1 content package/feed/day。
- デフォルト想定: Instagram formatを1つ選ぶ場合、48 platform publish jobs/day。
- 上限想定: 全コンテンツでInstagram CarouselとReelsを両方有効化した場合、64 platform publish jobs/day。

API実現性:

- Instagram: 通常1 post/account/day。CarouselとReelsを両方有効化しても最大2 posts/account/dayで、Sociofyの安全側guardrailである50 posts/account/dayを下回る。
- YouTube: 16 uploads/day ~= 1,600 quota units/day。補助calls前でdefault 10,000 units/dayを下回る。
- TikTok: 16 photo init calls/dayがアカウントに分散され、6 requests/min/user token limitを大きく下回る。
- OpenAI GPT Image 2: SmartScout初期では4 generated images/package x 16 packages/day = 64 generated images/dayを見込む。固定CTA画像は日次生成対象外。Approved assetsをcacheし、content packageごとにcost trackingする。
- Optional `zh-Hans`: SmartScoutで簡体字をactive化した場合は20 logical feeds、20 packages/day、80 generated images/day、default 60 jobs/day、max 80 jobs/dayに増える。

### 16.1 1日あたりの画像生成費用見積もり

この見積もりは、OpenAI API pricingを2026-05-25時点で確認した計画値である。実請求は選択する `quality`、`size`、prompt/input tokens、再生成回数、将来の価格改定で変わる。

前提:

- 16 content packages/day。
- 1 content packageあたりGPT Image 2で生成する画像は4枚。
- 固定CTA画像1枚は既存アセットを使うため、日次画像生成費用には含めない。
- 合計: 64 generated images/day。
- MVPの計画基準は `gpt-image-2`、portrait相当、medium quality。
- 参考単価はOpenAI公式docsのGPT Image 2 `1024 x 1536` 例を使う。実際の9:16出力サイズはprototype時にusage metadataで再計算する。

画像出力費用:

| quality | 参考単価/枚 | 64枚/日の画像出力費用 |
| --- | ---: | ---: |
| low | $0.005 | $0.32/day |
| medium | $0.041 | $2.62/day |
| high | $0.165 | $10.56/day |

Text input費用:

- GPT Image 2のtext input単価は$5.00 / 1M tokens。
- Promptを平均1,000 input tokens/imageと仮置きすると、64,000 tokens/day。
- 64,000 / 1,000,000 x $5.00 = $0.32/day。

MVP計画値:

- Medium quality画像出力 $2.62/day + text input概算 $0.32/day = 約 $2.94/day。
- 再生成、参照画像を使うedit、high quality指定、CTA画像の再生成は別途加算する。

主なボトルネックはrate limit量ではなく、platform audit/approval、token readiness、account readinessである。

## 17. 外部SaaS化準備

公開前にSociofyは以下を追加する。

- Multi-tenant organization model。
- Self-serve onboarding。
- Customer OAuth connection flows。
- Terms of service and privacy policy。
- Platform app review/audit completion for production permissions。
- Abuse reporting and account suspension controls。
- Per-tenant usage limits。
- Billing and plan enforcement。
- Customer-facing status page for platform incidents。
- Data retention settings。

外部公開時のプラットフォーム別ブロッカー:

- TikTok: Direct Postのpublic visibilityにはaudit approvalが必要。
- YouTube: newer projectsからのpublic API uploadsにはYouTube API Services auditが必要。
- Meta/Instagram: non-app-role users向けproduction useにはApp Reviewとapproved permissionsが必要。

## 18. プロダクトロードマップ

### Phase 0: 仕様とプロトタイプ

- 本仕様書を確定する。
- Local schema prototypeを作る。
- 手動EditorialAngle登録とLogicalFeed展開を試作する。
- GPT Image 2によるslide visual generationを検証する。
- Image and MP4 rendering pipelineを検証する。
- S3/CloudFront public media URL fetch behaviorを検証する。
- 各プラットフォームを1つの内部アカウントで手動テストする。

### Phase 1: 内部MVP

- Product/angle/feed setup。
- Content generation and localization。
- Review and approval UI。
- GPT Image 2 visual generation and static image renderer。
- Slideshow video renderer。
- Instagram Carousel/Reels adapter。
- TikTok Photo adapter。
- YouTube Shorts adapter。
- Scheduling and publish job dashboard。

### Phase 2: 運用強化

- Token refresh automation。
- Platform readiness dashboard。
- Retry/failure workflows。
- Content calendar。
- Basic analytics import。
- Prompt/template versioning。
- Bulk approval。

### Phase 3: 外部SaaS準備

- Tenant model。
- OAuth self-service。
- Billing。
- Permission system。
- Customer-facing onboarding。
- App review/audit materials。
- Policy and abuse controls。

## 19. 確定済み論点

- 言語はユーザー選択式。MVPでは少なくとも英語、スペイン語、韓国語、中国語に対応し、locale variantsをlogical feed単位で保存する。
- SmartScout初期の中国語運用は繁体字 `zh-Hant` をデフォルトにし、簡体字 `zh-Hans` はcandidateとして残す。
- 言語数は固定上限にしない。AI翻訳は拡張しやすいが、active化は投稿先アカウント、承認、品質確認、分析の準備状態で管理する。
- SmartScout初期の4つの編集切り口は既存運用から取り込み、人間が手動で定義・確認したものをSociofyへ登録する。AI/ChatGPTによる切り口提案、レコメンド、ランキングはMVP対象外にする。
- Public mediaはAWS S3に保存し、CloudFront上のSociofy-controlled custom media domainでplatform fetch URLsを配信する。
- 推奨stackはAWS優先構成。単一モノレポ、pnpm workspace、Turborepo、共有パッケージ、React SPA + MUI v7 + Emotion、S3 + CloudFront、TypeScript API、ECS Fargate、Aurora PostgreSQL Serverless v2または既存方針に合わせたRDS/Aurora PostgreSQL、TypeORM、SQS、EventBridge Scheduler、DB-backed thin orchestrator、Cognito、Secrets Manager、CloudWatch Logs、FFmpeg、Sharp、AWS CDK。本格モニタリングはMVP後に追加する。
- InstagramはCarouselとReelsの両方をサポートするが、承認者がcontent packageごとに有効formatを選ぶ。デフォルト推奨は1 packageにつき1 Instagram format。
- TikTokはMVPではPhoto Modeを使う。Video fallbackは延期する。
- Generated visualsはOpenAI GPT Image 2、モデルID `gpt-image-2` を使う。MVPでは1 packageあたり4枚を生成し、固定CTA画像1枚を再利用する。Final slide copyはstructured and editableに保ち、厳密なlocalized textが重要な場合はdeterministic compositionを使う。

## 20. 参照資料

公式資料確認日: 2026-05-26

- TikTok Content Posting API Get Started:
  https://developers.tiktok.com/doc/content-posting-api-get-started/
- TikTok Photo Post API:
  https://developers.tiktok.com/doc/content-posting-api-reference-photo-post/
- TikTok Direct Post Video API:
  https://developers.tiktok.com/doc/content-posting-api-reference-direct-post/
- TikTok Media Transfer Guide:
  https://developers.tiktok.com/doc/content-posting-api-media-transfer-guide/
- TikTok OAuth User Access Token Management:
  https://developers.tiktok.com/doc/oauth-user-access-token-management/
- TikTok API Rate Limits:
  https://developers.tiktok.com/doc/tiktok-api-v2-rate-limit/
- Instagram Content Publishing:
  https://developers.facebook.com/docs/instagram-platform/content-publishing/
- Instagram IG User Media:
  https://developers.facebook.com/docs/instagram-platform/instagram-graph-api/reference/ig-user/media
- Instagram IG User Media Publish:
  https://developers.facebook.com/docs/instagram-platform/instagram-graph-api/reference/ig-user/media_publish
- YouTube Data API `videos.insert`:
  https://developers.google.com/youtube/v3/docs/videos/insert
- YouTube Data API quota overview:
  https://developers.google.com/youtube/v3/getting-started#quota
- YouTube OAuth guide:
  https://developers.google.com/youtube/v3/guides/authentication
- YouTube Shorts upload help:
  https://support.google.com/youtube/answer/12779649
- OpenAI Image generation guide:
  https://developers.openai.com/api/docs/guides/image-generation
- OpenAI GPT Image 2 model:
  https://developers.openai.com/api/docs/models/gpt-image-2
- OpenAI API pricing:
  https://openai.com/api/pricing/
- Amazon S3 static website hosting:
  https://docs.aws.amazon.com/AmazonS3/latest/userguide/WebsiteHosting.html
- Amazon CloudFront Origin Access Control for S3:
  https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html
- Amazon ECS on AWS Fargate:
  https://docs.aws.amazon.com/AmazonECS/latest/developerguide/AWS_Fargate.html
- Amazon SQS Developer Guide:
  https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html
- Amazon EventBridge Scheduler:
  https://docs.aws.amazon.com/scheduler/latest/UserGuide/what-is-scheduler.html
- Amazon Cognito user pools:
  https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html
- Amazon Aurora Serverless v2:
  https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-serverless-v2.html
- AWS Secrets Manager:
  https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html
- Amazon CloudWatch:
  https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html
