import { PrismaClient } from '@prisma/client' import { hash, compare } from 'bcrypt' import { sign, verify } from 'jsonwebtoken' import { OpenAI } from 'openai' const prisma = new PrismaClient() const ai = new OpenAI({ apiKey: process.env.OPENAI_KEY }) async function createUserWithTransaction(data) { return await prisma.$transaction(async (tx) => { const hashedPassword = await hash(data.password, 12) const user = await tx.user.create({ data: { email: data.email, password: hashedPassword } }) await tx.profile.create({ data: { userId: user.id } }) await tx.auditLog.create({ data: { action: 'USER_CREATED', targetId: user.id } }) return user }) } const generateEmbedding = async (text) => { const response = await ai.embeddings.create({ model: 'text-embedding-3-small', input: text }) return response.data[0].embedding } async function semanticSearch(query, limit = 10) { const embedding = await generateEmbedding(query) return await prisma.$queryRaw` SELECT *, embedding <=> ${embedding}::vector AS distance FROM documents ORDER BY distance LIMIT ${limit} ` } const rateLimit = new Map() const checkRateLimit = (ip, max = 100) => { const now = Date.now() const window = rateLimit.get(ip) || { count: 0, start: now } if (now - window.start > 60000) return { count: 1, start: now } if (window.count >= max) throw new Error('Rate limit exceeded') return { ...window, count: window.count + 1 } } io.on('connection', (socket) => { socket.on('subscribe', async (roomId) => { const canAccess = await checkPermission(socket.userId, roomId) if (canAccess) socket.join(roomId) }) socket.on('update', async (data) => { await prisma.document.update({ where: { id: data.id }, data: { content: data.content, version: { increment: 1 } } }) io.to(data.roomId).emit('sync', data) }) }) const transformIdeas = async (prompt) => { const context = await semanticSearch(prompt) const completion = await ai.chat.completions.create({ model: 'gpt-4o', messages: [ { role: 'system', content: buildSystemPrompt(context) }, { role: 'user', content: prompt } ], stream: true }) return completion // It just works. } .glass { background: rgba(255,255,255,0.1); backdrop-filter: blur(12px); border: 1px solid rgba(255,255,255,0.2); } export const authMiddleware = async (req, res, next) => { try { const token = req.headers.authorization?.split(' ')[1] if (!token) throw new UnauthorizedError() const decoded = verify(token, process.env.JWT_SECRET) req.user = await prisma.user.findUniqueOrThrow({ where: { id: decoded.sub }, include: { roles: true } }) next() } catch (e) { next(e) } } const imagine = async () => await transformIdeas('anything')
SERVICE 09 – 13

INHOUSE WEB BUILDING

コードを書く時代から、コードを操る時代へ

自社でサイト構築

yourcompany.co.jp Your Company Services Case Study About 相談 RESKILLING FOR AI ERA 28 SKILLS ビジネスを変革する28のスキル 詳細 資料DL 4 SKILL CATEGORIES AI CREATIVE 画像・動画・音声 01-08 WEB & APP サイト・アプリ開発 09-19 DATA 収集・分析・可視化 20-22 DX 業務改善・自動化 22-28 3 STEPS TO START 1 無料相談 2 プラン設計 3 研修開始 VOICE 「外注していた業務を 社内で回せるように」 — 製造業 A社様 「AIへの苦手意識が 完全になくなった」 — 小売業 B社様 「社員が自発的に 学ぶようになった」 — IT企業 C社様 「制作期間が 1/3に短縮できた」 — 広告代理店 D社様 まずは無料相談から 御社の課題に合わせた最適なプランをご提案します お問い合わせ NOTE この資料はAIコーディングで書かれた ホームページと同じテキストコードです。 Your Company AI時代のリスキリング支援 〒100-0001 東京都千代田区 Services Case Study About Us Contact Privacy Terms © 2026 Your Company Inc.
外注依存からの脱却

「Webサイトは外注するもの」という常識は終わりました。修正のたびに見積もり、更新のたびに請求——そのコストと時間は、本来ビジネスに使えるはずのリソースです。

AIの登場により、コードを書けなくてもWebサイトは作れます。必要なのは「何を伝えたいか」を明確にすることだけ。デザインもコードもAIがサポートします。

自社開発で得られるもの

外注の都合で更新を待つこともなくなります。コストも年間1400円程度に抑えることが可能。社内に知識がたまるだけでなく、AIを使える人材が増えていきます。

最初の一歩

まずは1ページから。ランディングページ、採用ページ、キャンペーンサイト——小さく始めて、成功体験を積み重ねる。それが自社Web内製化への最短ルートです。

TIPS

すべてお教えします。あなたの会社にWEB受注が可能な部署が誕生します。

AIコーディングの基礎

Claude UI screenshot
AIコーディングツール

Claude — Anthropic製。長文理解と正確性に強み。コード生成の品質が高い。

ChatGPT — OpenAI製。汎用性が高く情報も豊富。

Gemini — Google製。大規模コンテキストと多言語対応。無料枠が太っ腹。

Cursor — AI特化エディタ。コードベース全体を理解して提案。

Antigravity — Google製。エージェント優先IDE。複数AIが自律的にタスク実行。

使われる言語

HTML / CSS — Webの見た目を作る。最も基本。

JavaScript — 動きをつける。React、Vue等のフレームワークも。

Python — 自動化、データ分析、AI連携に強い。

TypeScript — JavaScriptに型をつけて安全に。大規模開発向け。

「動く」と「正しい」は違う

AIは「動くコード」を書くのは得意。でも「正しいコード」とは限らない。

セキュリティ、パフォーマンス、保守性——これらは指示しないと考慮されないことが多い。「動いたからOK」で終わらせると、後で痛い目を見る。

ディレクション力が鍵

AIは優秀だが、指示待ち。「いい感じにして」では「いい感じ」にならない。

何を作るか、どう作るか、何を守るか——これを明確に伝えられる人が、AIを使いこなせる。

丸投げ vs 対話

一発で完璧なコードは出てこない。対話しながら修正、確認、改善を繰り返す。これが「バイブコーディング」の本質。雰囲気で任せるのではなく、対話で育てる。

生成コードに潜む脆弱性の回避

FRONTEND 見た目・UI → 信用しない。誰でも改ざん可能 ⚠ パスワードが丸見え ⚠ 誰でも侵入できる穴 SERVER / RULES バックエンド → ここで本当の守りを固める ✓ Firebase Rules / ログイン確認 ✓ 悪意ある入力をブロック
AIが作る「動くコード」の落とし穴
AIは「とりあえず動く」を優先しがち。パスワードが丸見えだったり、悪い人が侵入できる穴が開いてることも。警告が出ても意味がわからなければスルーしちゃう。
「表」と「裏」があることを知ろう
画面に見えてる部分は誰でも覗ける・いじれる。大事な処理は「裏側」でやらないとダメ。この2つがあることを知ってるだけで、大きな事故は防げる。
従来型(WordPress等)はもっと大変
追加機能から穴が開きやすい、更新をサボると即狙われる、守りは全部自分でやらないといけない。世界中のハッカーに狙われてる。「昔からある=安全」じゃないんです。
AIへの指示を忘れずに
□ 「セキュリティを考慮して」と伝える
□ 「APIキーが外から見えないように」と頼む
□ 「悪意のある入力を防いで」と確認する
□ 「このコードに問題ないか確認して」と聞く
新しい作り方なら守りやすい
Firebase + シンプルなサイト構成なら、狙われるポイントが少ない。設定画面でセキュリティを一括管理できる。サーバーの面倒もGoogleが見てくれる。
まとめ
AIに任せきりは怖いけど、ちゃんとお願いすれば従来より安全に作れる。「わからないから全部お任せ」が一番キケン。
GLOSSARY
API
アプリ同士をつなぐ「合言葉」のようなもの。これが漏れると他人に勝手に使われちゃう。
フロントエンド
画面に見えてる部分。お店の「売り場」みたいなもの。誰でも見れるし触れる。
SQLサーバー
会員情報や商品データを保管する倉庫。ハッカーが一番狙いたい場所。
バックエンド
裏で動いてる部分。お店の「バックヤード」。大事なものはここで守る。

外注削減とセキュリティ管理

SKILL 11 外注削減とセキュリティ管理
内製 + AI
速い・安い・自由
普通のWEBサイトなら10年で
¥2,500,000
コストカットになります。

修正のたびに見積もり、更新のたびに請求——
その繰り返し、もう終わりにしませんか。

10年間のコスト比較

外注 内製 + AI YEAR 0 ¥500,000 初期制作 ¥0 自分で作る YEAR 1-5 ¥750,000 保守 15万/年 × 5 ¥180,000 ¥36,000/年 × 5 修正・更新 ¥500,000 5万 × 10回 ¥0 いつでも自分で YEAR 6-10 ¥750,000 保守 15万/年 × 5 ¥180,000 ¥36,000/年 × 5 10 YEARS TOTAL ¥2,500,000 ¥374,000
Claude Pro ¥36,000/年
Anthropic製AIアシスタント。設計・要件整理・コード生成・レビューまで対話しながら進められる。Claude Code CLIと組み合わせれば、ターミナルから直接コードベースを操作可能。
Antigravity ¥0
Google製のエージェント優先IDE。現在無料プレビュー中。複数のAIが自律的にタスクを分担し、指示ひとつでファイル横断の実装が完結する。
Cursor Pro ¥36,000/年
AIコーディングエディタの定番。コードベース全体を理解した上で補完・リファクタリング・バグ修正を提案する。Antigravityの代替として、または併用も可。
Firebase ¥0
Googleのフルマネージドプラットフォーム。Hosting・Authentication・Firestore(DB)をひとつのコンソールで管理できる。中小規模サイトなら無料枠で十分運用可能。
GCP 従量課金
Googleクラウドインフラ。Firebaseと同じエコシステムのため連携がスムーズ。アクセス急増や大容量データ処理など、規模拡大が必要になったタイミングで移行・併用する。
ドメイン ¥1,400/年~
独自ドメイン取得・維持費。Google Domains(Squarespace Domains)やお名前.comなどで取得。年間¥1,400程度から。
サーバー ¥0/年~
FirebaseのHosting無料枠を使えばサーバー代は実質¥0。月10GBのストレージ・転送量まで無料。超過した場合のみ従量課金が発生する。
内製化、サポートします。
ツールの選定から初期構築、運用の定着まで。
「自分でできる」状態になるまで、しっかり伴走します。

セキュリティ管理:会員管理

SECURITY & MEMBERSHIP MANAGEMENT

ACCESS CONTROL SYSTEM Authentication ログイン 本人確認 Authorization 権限確認 アクセス権判定 GRANTED データ表示 DENIED アクセス拒否 「ログインできる」と「見ていい」は別の話 Authentication ≠ Authorization
認証と認可を混同すると何が起きるか

Firebase Authenticationは「本人確認」を行う仕組みであり、「見せていいか」の判定は別途設計が必要です。

「ログイン済みならOK」という設定では、悪意あるユーザーが他人の注文履歴や個人情報を自由に閲覧できてしまいます。会員ランク別の卸価格も要注意。

INCIDENT
2024年、セキュリティルールの設定不備により900以上のサイトで1.25億件の個人情報が公開状態に。わずか72時間300万円以上の不正請求が発生した事例も。
初心者がやりがちな設定ミス
× allow read: if true;
誰でも全データ読み取り可能
× if request.auth != null;
ログイン済みなら他人のデータも見放題
× フロントで価格を切り替え
ブラウザで書き換えて卸価格で購入
× UIDをそのまま信用
他人のIDを偽装してリクエスト
正しい設計

・ セキュリティルールで「誰が何を操作できるか」を最小権限で定義
・ サーバーサイドでIDトークンを検証
・ 価格決定は必ずバックエンドで

F12キーで見えてしまうものから守る

F12
押してみてください。
あなたのサイト、丸見えです。
開発者ツールを使えば、HTMLもCSSもJavaScriptの変数も、
サーバーへ送るデータも、すべて書き換えられます。
ATTACK 01
HTMLを直接編集
数量制限の max="3" を消すだけ。
「お一人様3点まで」が無意味に。
<input max="3"> → <input max="999">
ATTACK 02
変数を書き換え
コンソールで価格変数を0に。
1万円の商品が0円で注文される。
price = 0;
ATTACK 03
会員ランクを偽装
localStorageの値を書き換え。
一般客が卸価格で購入。
userRank = 'wholesale';
ATTACK 04
通信データを改ざん
Networkタブでリクエストを傍受。
金額を書き換えてサーバーへ送信。
amount: 10000 → amount: 1
価格改ざん
10,000円の商品を100円で決済。サーバーで再計算していなければ、そのまま通る。
クーポン不正利用
「一人一回限り」のチェック関数を return true; に書き換え、無限に使用。
在庫制限突破
限定1点の商品を100個注文。発送不能でクレームの嵐。
サーバールールが「鉄の門」。
ルール構築が甘いと、F12ひとつで改ざんされます。
① F12キーで見られるところに肝心な情報は書かない。
② アクセスする人間は全員がハッカーであるという前提で構築。
③ サーバーに格納した情報にブラウザから侵入されないようなサーバールールの構築。
フロントエンドの認証機能などの入力チェックは南京錠程度の強度でしかない。