Skip to content

Commit b7d723d

Browse files
authored
Merge pull request #2 from nagauta/feat/db-setup
feat: DB setup, seed, README
2 parents 6a0f670 + ee493e7 commit b7d723d

12 files changed

Lines changed: 207 additions & 8 deletions

File tree

README.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# nagauta-stack
2+
3+
個人開発のベースとなるテンプレートレポジトリ。
4+
5+
## 技術スタック
6+
7+
| カテゴリ | 技術 |
8+
|---------|------|
9+
| FW | Hono |
10+
| フロント | htmx |
11+
| CSS | Tailwind CSS |
12+
| DB | PostgreSQL + Drizzle ORM |
13+
| バリデーション | Zod |
14+
| コンテナ | Docker |
15+
| モノレポ | pnpm + Turborepo |
16+
| Lint / Format | Biome |
17+
| Git Hooks | Lefthook |
18+
| テスト | Vitest + Playwright |
19+
| CI/CD | GitHub Actions |
20+
| 依存更新 | Renovate |
21+
22+
## 構成
23+
24+
```
25+
apps/
26+
web/ # Hono アプリ
27+
packages/
28+
config/ # 共有設定 (tsconfig)
29+
```
30+
31+
## セットアップ
32+
33+
```bash
34+
pnpm install
35+
docker compose up -d
36+
cp apps/web/.env.example apps/web/.env
37+
pnpm --filter @nagauta-stack/web db:migrate
38+
pnpm --filter @nagauta-stack/web db:seed
39+
```
40+
41+
## 開発
42+
43+
```bash
44+
pnpm dev
45+
```
46+
47+
## コマンド
48+
49+
| コマンド | 説明 |
50+
|---------|------|
51+
| `pnpm dev` | 開発サーバー起動 |
52+
| `pnpm build` | ビルド |
53+
| `pnpm lint` | Lint / Format チェック |
54+
| `pnpm lint:fix` | Lint / Format 自動修正 |
55+
| `pnpm check-types` | 型チェック |
56+
| `pnpm test` | テスト実行 |
57+
| `pnpm --filter @nagauta-stack/web db:generate` | マイグレーションファイル生成 |
58+
| `pnpm --filter @nagauta-stack/web db:migrate` | マイグレーション実行 |
59+
| `pnpm --filter @nagauta-stack/web db:seed` | Seedデータ投入 |
60+
| `pnpm --filter @nagauta-stack/web db:studio` | Drizzle Studio起動 |
File renamed without changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CREATE TABLE "examples" (
2+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3+
"title" text NOT NULL,
4+
"created_at" timestamp DEFAULT now() NOT NULL
5+
);
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"id": "c3bec21b-9eef-4704-8f29-055429c8946c",
3+
"prevId": "00000000-0000-0000-0000-000000000000",
4+
"version": "7",
5+
"dialect": "postgresql",
6+
"tables": {
7+
"public.examples": {
8+
"name": "examples",
9+
"schema": "",
10+
"columns": {
11+
"id": {
12+
"name": "id",
13+
"type": "uuid",
14+
"primaryKey": true,
15+
"notNull": true,
16+
"default": "gen_random_uuid()"
17+
},
18+
"title": {
19+
"name": "title",
20+
"type": "text",
21+
"primaryKey": false,
22+
"notNull": true
23+
},
24+
"created_at": {
25+
"name": "created_at",
26+
"type": "timestamp",
27+
"primaryKey": false,
28+
"notNull": true,
29+
"default": "now()"
30+
}
31+
},
32+
"indexes": {},
33+
"foreignKeys": {},
34+
"compositePrimaryKeys": {},
35+
"uniqueConstraints": {},
36+
"policies": {},
37+
"checkConstraints": {},
38+
"isRLSEnabled": false
39+
}
40+
},
41+
"enums": {},
42+
"schemas": {},
43+
"sequences": {},
44+
"roles": {},
45+
"policies": {},
46+
"views": {},
47+
"_meta": {
48+
"columns": {},
49+
"schemas": {},
50+
"tables": {}
51+
}
52+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"version": "7",
3+
"dialect": "postgresql",
4+
"entries": [
5+
{
6+
"idx": 0,
7+
"version": "7",
8+
"when": 1771071607317,
9+
"tag": "0000_easy_electro",
10+
"breakpoints": true
11+
}
12+
]
13+
}

apps/web/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88
"db:generate": "drizzle-kit generate",
99
"db:migrate": "drizzle-kit migrate",
1010
"db:studio": "drizzle-kit studio",
11+
"db:seed": "tsx src/db/seed.ts",
1112
"test": "vitest run",
1213
"test:watch": "vitest",
1314
"test:e2e": "playwright test"
1415
},
1516
"dependencies": {
1617
"@hono/node-server": "^1.19.9",
18+
"dotenv": "^17.3.1",
1719
"drizzle-orm": "^0.45.1",
1820
"hono": "^4.0.0",
1921
"postgres": "^3.4.8",

apps/web/src/db/index.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,16 @@ import { drizzle } from "drizzle-orm/postgres-js";
22
import postgres from "postgres";
33
import * as schema from "./schema";
44

5-
const databaseUrl = process.env.DATABASE_URL;
6-
if (!databaseUrl) {
7-
throw new Error("DATABASE_URL is not set");
8-
}
5+
let _db: ReturnType<typeof drizzle<typeof schema>> | null = null;
96

10-
const client = postgres(databaseUrl);
11-
export const db = drizzle(client, { schema });
7+
export function getDb() {
8+
if (!_db) {
9+
const databaseUrl = process.env.DATABASE_URL;
10+
if (!databaseUrl) {
11+
throw new Error("DATABASE_URL is not set");
12+
}
13+
const client = postgres(databaseUrl);
14+
_db = drizzle(client, { schema });
15+
}
16+
return _db;
17+
}

apps/web/src/db/seed.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import "dotenv/config";
2+
import { drizzle } from "drizzle-orm/postgres-js";
3+
import postgres from "postgres";
4+
import { examples } from "./schema";
5+
6+
const databaseUrl = process.env.DATABASE_URL;
7+
if (!databaseUrl) {
8+
throw new Error("DATABASE_URL is not set");
9+
}
10+
11+
const client = postgres(databaseUrl);
12+
const db = drizzle(client);
13+
14+
async function seed() {
15+
console.log("Seeding...");
16+
17+
await db
18+
.insert(examples)
19+
.values([
20+
{ title: "Example 1" },
21+
{ title: "Example 2" },
22+
{ title: "Example 3" },
23+
]);
24+
25+
console.log("Seeding done.");
26+
}
27+
28+
seed()
29+
.catch(console.error)
30+
.finally(() => client.end());

apps/web/src/routes/api.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { eq } from "drizzle-orm";
22
import { Hono } from "hono";
33
import { z } from "zod/v4";
4-
import { db } from "../db";
4+
import { getDb } from "../db";
55
import { examples } from "../db/schema";
66
import { ExampleItem } from "../views/partials/example-item";
77

@@ -12,6 +12,7 @@ const createExampleSchema = z.object({
1212
});
1313

1414
app.get("/examples", async (c) => {
15+
const db = getDb();
1516
const items = await db.select().from(examples);
1617
return c.html(
1718
<>
@@ -23,6 +24,7 @@ app.get("/examples", async (c) => {
2324
});
2425

2526
app.post("/examples", async (c) => {
27+
const db = getDb();
2628
const body = await c.req.parseBody();
2729
const parsed = createExampleSchema.safeParse(body);
2830
if (!parsed.success) {
@@ -40,6 +42,7 @@ app.post("/examples", async (c) => {
4042
});
4143

4244
app.delete("/examples/:id", async (c) => {
45+
const db = getDb();
4346
const id = c.req.param("id");
4447
await db.delete(examples).where(eq(examples.id, id));
4548
return c.body(null, 200);

biome.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@
2020
"indentStyle": "tab"
2121
},
2222
"files": {
23-
"ignore": ["node_modules", "dist", "public/styles.css", ".turbo"]
23+
"ignore": [
24+
"node_modules",
25+
"dist",
26+
"public/styles.css",
27+
".turbo",
28+
"apps/web/drizzle"
29+
]
2430
}
2531
}

0 commit comments

Comments
 (0)